經典演算法之Floyd演算法(求圖中任意一對頂點間的最短路徑)
阿新 • • 發佈:2019-01-05
/************************ author's email:[email protected] date:2018.1.30 ************************/ /* 佛洛伊德演算法思想: 1)設定兩個矩陣A和Path,初始時將圖的鄰接矩陣賦值給A,將矩陣Path中元素全部設定為-1 2)以頂點k為中間頂點,k取0——n-1(n為圖中頂點個位),為圖中所有頂點對{i,j}進行如下檢測與修改: 如果A[i][j]>A[i][k]+A[k][j],則將A[i][j]改為A[i][k]+A[k][j]的值,將path[i][j]改為k,否則 什麼都不做。 佛洛伊德演算法的時間複雜度分析: 由演算法程式碼可知,本演算法的主要部分是一個三層順序,取內層迴圈的操作作為基本操作,則 基本操作的執行次數為n^3,因此時間複雜度為O(n^3)。 */ #include<iostream> #define INF 100//INF為比圖中任何權值都大的數 #define maxSize 4 //圖的頂點數 #define number 8 //圖的邊數 using namespace std; typedef struct {//圖的定義 int edges[maxSize][maxSize];//鄰接矩陣的定義 int n, e; //分別為頂點數和邊數 }MGraph; MGraph createGraph(MGraph g); void Floyd(MGraph g, int A[][maxSize],int path[][maxSize]);//佛洛伊德演算法 void printPath(int u, int v, int path[][maxSize]);/*遞迴輸出從u到v的最短路徑頂點序列*/ int main() { MGraph g;//定義並初始化圖g g.edges[maxSize][maxSize] = { 0 }; g.n = maxSize; g.e = number; g = createGraph(g);//建立一個圖 int A[maxSize][maxSize] ; int path[maxSize][maxSize] ; int u, v;//定義起始點和終點 u = 1,v=0; Floyd(g, A, path); cout << "從" << u << "點到" << v << "點的最短路徑為:" << endl; cout << u << " "; printPath(u, v, path); cout << v << endl; cout << "從" << u << "點到" << v << "點的最短路徑長度為:" <<A[u][v]<< endl; system("pause"); return 0; } MGraph createGraph(MGraph g) {//此圖為一個正方形,按順時針順序圖的各頂點為0,1,2,3 int i, j; for (i = 0; i < maxSize; i++) { for (j = 0; j < maxSize; j++) { g.edges[i][j] = INF; } } g.edges[0][1] = 5; g.edges[0][3] = 7; g.edges[2][0] = 3; g.edges[1][2] = 4; g.edges[2][1] = 3; g.edges[2][3] = 2; g.edges[3][2] = 1; g.edges[1][3] = 2; g.n = maxSize; g.e = number; return g; } void Floyd(MGraph g, int A[][maxSize],int path[][maxSize]) { int i, j, k; //對陣列A[][]和path[][]進行初始化 for (i = 0; i < g.n; ++i) { for (j = 0; j < g.n; ++j) { A[i][j] = g.edges[i][j]; path[i][j] = -1; } } /*下面這個三層迴圈是本演算法的主要操作,完成了以k為中間點對所有頂點對{i,j} 進行檢測和修改*/ for (k = 0; k < g.n; ++k) { for (i = 0; i < g.n; ++i) { for (j = 0; j < g.n; ++j) { if (A[i][j] >( A[i][k] + A[k][j])) { A[i][j] = A[i][k] + A[k][j]; path[i][j] = k; } } } } } void printPath(int u, int v, int path[][maxSize]) /*遞迴輸出從u到v的最短路徑頂點序列*/ { if (path[u][v] == -1) return; else { cout<< path[u][v] << " "; int mid = path[u][v]; printPath(u, mid, path);//處理mid前半段路徑 printPath(mid, v, path);//處理mid後半段路徑 } }