Floyd(動態規劃)求解任意兩點間的最短路徑(圖解)
阿新 • • 發佈:2021-11-08
Floyd演算法的精髓在於動態規劃的思想,即每次找最優解時都建立在上一次最優解的基礎上,當演算法執行完畢時一定是最優解
對於鄰接矩陣w,w儲存最初始情況下任意兩點間的直接最短距離,但沒有加入中繼點進行考慮
如w[1][2]=20,即表示點1與點2的當前最短距離(直接距離)為20
對於路徑矩陣path,儲存了點i到點j的最短路徑中下一個點的位置,
如path[1][2]=0,表示1->2的路徑中的下一個點為結點0
Floyd演算法對所有中繼點在任意兩點中進行迴圈遍歷.即k從0-n時考慮(i->k,k->j)的路徑是否小於(i->j)的路,如果小於即更新鄰接矩陣w的值與path矩陣中的值,使其始終保持最短
圖解如下:
程式碼用例:
程式碼如下
點選檢視程式碼
#include<iostream> #include<fstream> #include<vector> using namespace std; const int MAX = 999; class Solution { public: void GetPath(vector<vector<int>>vec,int n) { vector<vector<int>>path(n); //初始化 for (int i = 0; i != n; i++) path[i].resize(n); for(int i=0;i!=n;i++) for (int j = 0; j != n; j++) { if (vec[i][j] != MAX)path[i][j] = j; else path[i][j] = -1; } for (int i = 0; i < n; i++)path[i][i] = -1; for(int k=0;k!=n;k++) for(int i=0;i!=n;i++) for (int j = 0; j != n; j++) { if (vec[i][k] + vec[k][j] < vec[i][j]) { vec[i][j] = vec[i][k] + vec[k][j]; path[i][j] = path[i][k]; } } for (int i = 0; i != n; i++) { cout << "\nStating from vertex: " << i << endl; bool flag = 0; for (int j = 0; j != n; j++) if (j != i && vec[i][j] < MAX) { flag = 1; cout << i << "->" << j << ":distance=" << vec[i][j] << ": " << i; int k = path[i][j]; while (k != j) { cout << "->" << k; k = path[k][j]; } cout << "->" << j << endl; } if (!flag)cout << "there's no path while starting from "<<i<<endl; } } }; int main() { ifstream putIn("D:\\Input.txt", ios::in); int num; int finalCount = 0; putIn >> num; const int x = num; vector<vector<int>>myVector(num); //myVector:帶權鄰接矩陣 for (int i = 0; i < num; i++) myVector[i].resize(num); for (int i = 0; i < num; i++) for (int j = 0; j < num; j++) { int temp; putIn >> temp; myVector[i][j] = temp; } Solution solution; cout << "Input檔案中的鄰接矩陣為\n"; for (auto x : myVector) { for (auto y : x)cout << y << '\t'; cout << endl; } solution.GetPath(myVector,num); return 0; }