最短路徑問題
昨天自己試了試寫一下dijkstra的演算法部落格
今天來更floyd演算法,感覺非常簡單果然暴力才是解決一切的王道
一、總體思想
floyd演算法就是每一次從鄰接矩陣選取一個頂點k,然後再去矩陣中遍歷兩個頂點i,j,看看是i→j的路徑短,還是i→k→j的路徑短,就是完全的暴力,演算法和程式碼非常簡單
二、程式碼實現
1 void Floyd(Graph G) 2 { 3 int arr[G.vexnum][G.vexnum]; 4 for(int i = 0; i < G.vexnum; i++) 5 for(int j = 0; j < G.vexnum; i++) 6 arr[i][j] = G.edge[i][j]; 7 8 for(int k; k < G.vexnum; k++) 9 for(int i = 0; i < G.vexnum; i++) 10 for(int j = 0; j < G.vexnum; j++) 11 if(arr[i][j] > arr[i][k] + arr[k][j]) 12 arr[i][j] = arr[i][k] + arr[k][j]; 13 }
三、程式碼解釋
其實看上面的程式碼量和程式碼就知道這個演算法很簡單 =_=
傳入Floyd演算法的引數是Graph G
首先開闢一個二維陣列arr[][],並且把圖的鄰接矩陣G.edge[][]賦值給arr[][],演算法的主要思想就是來修改arr[][]值暴力出最短路徑
1 int arr[G.vexnum][G.vexnum];//開闢陣列arr[][]接收圖G.edge[][]的值 2 for(int i = 0; i < G.vexnum; i++) 3 for(int j = 0; j < G.vexnum; i++) 4 arr[i][j] = G.edge[i][j];//遍歷賦值
然後就是每次選擇一個頂點k,再去找兩個頂點i,j,對比看看是i→j的路徑短,還是i→k→j的路徑短
也就是arr[i][j] 和 arr[i][k] + arr[k][j]兩個的值誰的比較小,然後修改arr[][]一直到遍歷完畢
1 for(int k; k < G.vexnum; k++)//選取k頂點 2 for(int i = 0; i < G.vexnum; i++) 3 for(int j = 0; j < G.vexnum; j++)//再選取i,j兩個頂點 4 if(arr[i][j] > arr[i][k] + arr[k][j])//判斷i→j的路徑和i→k→j的路徑誰比較短 5 arr[i][j] = arr[i][k] + arr[k][j];//如果i→k→j的路徑更短,則修改陣列arr[][]
寫完感覺好短。。不過確實沒啥寫的,就是O(n3)的暴力,而且這個演算法能計算含有負權值的圖,dijkstra就不行
雖然dijkstra的演算法只有O(n2),但是它只有一個頂點到剩下頂點的最短路徑,如果還是要計算每個點到每個點的最短路徑,其實和Floyd一樣,也是O(n3)
最重要的是 ——Floyd演算法他好記啊!