Floyd演算法思想

2021-09-06 17:21:07 字數 1616 閱讀 6478

floyd演算法是乙個經典的動態規劃演算法。用通俗的語言來描述的話,首先我們的目標是尋找從點i到點j的最短路徑。從動態規劃的角度看問題,我們需要為這個目標重新做乙個詮釋(這個詮釋正是動態規劃最富創造力的精華所在),floyd演算法加入了這個概念

ak(i,j):表示從i到j中途不經過索引比k大的點的最短路徑。 

這個限制的重要之處在於,它將最短路徑的概念做了限制,使得該限制有機會滿足迭代關係,這個迭代關係就在於研究:假設ak(i,j)已知,是否可以藉此推導出ak-1(i,j)。 

假設我現在要得到ak(i,j),而此時ak(i,j)已知,那麼我可以分兩種情況來看待問題:1. ak(i,j)沿途經過點k;2. ak(i,j)不經過點k。如果經過點k,那麼很顯然,ak(i,j) = ak-1(i,k) + ak-1(k,j),為什麼是ak-1呢?因為對(i,k)和(k,j),由於k本身就是源點(或者說終點),加上我們求的是ak(i,j),所以滿足不經過比k大的點的條件限制,且已經不會經過點k,故得出了ak-1這個值。那麼遇到第二種情況,ak(i,j)不經過點k時,由於沒有經過點k,所以根據概念,可以得出ak(i,j)=ak-1(i,j)。現在,我們確信有且只有這兩種情況---不是經過點k,就是不經過點k,沒有第三種情況了,條件很完整,那麼是選擇哪乙個呢?很簡單,求的是最短路徑,當然是哪個最短,求取哪個,故得出式子: 

ak(i,j) = min( ak-1(i,j), ak-1(i,k) + ak-1(k,j) )

因此floyd的最外層迴圈:

for (k = 0; k < n; k++) ...

就是分別求出 a0(i,j), a1(i,j), ..., an(i,j) 

演算法描述:

(1) 用陣列dis[i][j]來記錄i,j之間的最短距離。初始化dis[i][j],

若i=j則dis[i][j]=0,

若i,j之間有邊連線則dis[i][j]的值為該邊的權值,否則dis[i][j]的值為 。

(2) 對所有的k值從1到n,修正任意兩點之間的最短距離,計算dis[i][k]+dis[k][j]的值,若小於dis[i][j],則dis[i][j]= dis[i][k]+dis[k][j],否則dis[i][j]的值不變

程式:

1

void floyd(int dis[n + 1][n + 1], int path[n + 1][n + 1], intn)2

11}12}

13}14 }

正確性證明(歸納法) :

對於任意兩點a,b:

(1)當從a到b之間的最短路徑,在中間沒有經過頂點或經過1個頂點號為1的頂點時,演算法顯然正確。

(2)假設a到b經過的最大頂點號不超過k-1時,演算法得到的最短距離是正確的

(3)當a到b經過的最大頂點號為k時,則從a到頂點號為k的頂點v 之間的頂點號均不大於k-1,從v 到b之間的頂點號也不大於k-1,由假設2得,

a到vk的距離是中間頂點號不超過k-1的最短距離,vk到b的距離是中間頂點號不超過k-1的最短距離,所以a經vk到b為a,b之間經過最大號

為k的路徑中距離最短的,由演算法修正a,b的最短距離,即可得到a,b間頂點號不超過k的最短距離。

(4)綜上所述,演算法是正確的

時間複雜度:o(n3)

Floyd演算法思想

本來 量如此小的演算法不用出模板了,但是的確思想還是很好的。1.定義概覽 floyd warshall演算法 floyd warshall algorithm 是解決任意兩點間的最短路徑的一種演算法,可以正確處理有向圖或負權的最短路徑問題,同時也被用於計算有向圖的傳遞閉包。floyd warshal...

Floyd演算法簡介

演算法定義 floyd warshall演算法 floyd warshall algorithm 是解決任意兩點間的最短路徑的一種演算法,可以正確處理有向圖或負權的最短路徑問題,同時也被用於計算有向圖的傳遞閉包。floyd warshall演算法的時間複雜度為o n 3 空間複雜度為o n2 演算法...

Floyd演算法 模板

floyd演算法又稱為插點法,是一種用於尋找給定的加權圖中多源點之間最短路徑的演算法。該演算法名稱以創始人之一 1978年圖靈獎獲得者 史丹福大學電腦科學系教授羅伯特 弗洛伊德命名。注意 其實很多題目不是直接問你 floyd 怎麼求最短路徑,而是要你利用 floyd 的動態規劃思想解決類似 floy...