Floyd演算法之個人見解
Floyd演算法之個人見解
因為最近有一個演算法作業要交- -,我看了看題目,大致就是帶權值求最短路徑。所以我想到了弗洛伊德演算法,我就去看了看百度,然後做個總結吧。
假如我們去旅遊,肯定希望少走冤枉路,那麼我們就要知道任何兩個地方最短的距離。
這四個地方,有八條公路可以到達,請注意這些公路是單向的。我們現在需要求任意兩個城市之間的最短路程,也就是求任意兩個點之間的最短路徑。這個問題這也被稱為“多源最短路徑”問題。
現在我們需要一個二維陣列來儲存它,可以建立一個4*4矩陣,比如1號城市到2號城市的路程為2,則設e[1][2]的值為2。2號城市無法到達4號城市,則設定e[2][4]的值為∞。另外此處約定一個城市自己是到自己的也是0,例如e[1][1]為0,具體如下。
我們知道,如果要縮短兩點的距離就只有引入中轉點(頂點k)使其路程變短(即a->k->b),有時候可能要兩個中轉點或者更多的點才會讓其路程變得更短,也就是引入k1、k2、k3等等(即a->k1->k2…->k->i…->b),例如上圖,原來4->3路程是12,如果經過1之後變成4->1->3那麼路程就變成了11了(即e[4][1]+e[1][3]=5+6=11)。所以現在將問題轉化成一般情況。
- 不經過別的中轉點
- 經過中轉點1
只經過中轉點1應該怎麼求呢?只需判斷e[i][1]+e[1][j]是否比e[i][j]要小即可,e[i][j]表示的是從i號頂點到j號頂點之間的路程。e[i][1]+e[1][j]表示的是從i號頂點先到1號頂點,再從1號頂點到j號頂點的路程之和。程式碼實現如下。
for (i = 1; i <= n; i++)
{
for (j = 1; j <= n; j++)
{
//迴圈是遍歷整個矩陣,判斷每個點經過1是否會變小
if (e[i][j] > e[i][1] + e[1][j])
e[i][j] = e[i][1] + e[1][j];
}
}
經過1之後,路程表更新為:
通過上圖我們可以發現,標白的三個地方的路程經過1到其他點的路程變短了。
- 經過1、2中轉點
接下來只循序經過1、2會怎麼樣呢?我們需要在只允許經過1號頂點時任意兩點的最短路程的結果下,再判斷如果經過2號頂點是否可以使得i號頂點到j號頂點之間的路程變得更短。即判斷e[i][2]+e[2][j]是否比e[i][j]要小,程式碼實現為如下。
//經過1號頂點
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
if (e[i][j] > e[i][1]+e[1][j]) e[i][j]=e[i][1]+e[1][j];
}
}
//經過2號頂點
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
if (e[i][j] > e[i][2]+e[2][j]) e[i][j]=e[i][2]+e[2][j];
}
}
在只允許經過1和2號頂點的情況下,任意兩點之間的最短路程更新為:
我們可以發現之前的4->3經過1(4->1->3)變成了11,現在又經過了2(4->1->2->3)變成了10,
- 經過1、2、3中轉點
同理,繼續在只允許經過1、2和3號頂點進行中轉的情況下,求任意兩點之間的最短路程。任意兩點之間的最短路程更新為:
- 經過所有中轉點
最後允許通過所有頂點作為中轉,任意兩點之間最終的最短路程為:
整個過程其實可以簡化為幾行程式碼:
for(k=0; k<n ; k++){ //簡單的說就是更新二維矩陣,將任何一個點經過任何一箇中間點之後的路程更新為最短的距離
//一句話概括就是:從i號頂點到j號頂點只經過前k號點的最短路程。
for(i =0; i<n; i++){
for(j=0; j<n; j++){
if(e[i][j] > (e[i][k] + e[k][j])){
e[i][j] = e[i][k] + e[k][j];
}
}
}
}
上面就是經過所有的中轉點,求的到任意點最短的距離。簡單的說就是從i號頂點到j號頂點只經過前k號點的最短路程。
相關文章
- 最短路演算法之:floyd 演算法演算法
- 最短路徑之Floyd演算法演算法
- Java Enum 個人見解Java
- 遞增排序個人見解排序
- 【圖論】Floyd演算法圖論演算法
- Floyd最短路演算法演算法
- Dijkstra演算法和Floyd演算法超詳解以及區別演算法
- 最短路徑(Floyd演算法)演算法
- 最短路-SPFA演算法&Floyd演算法演算法
- 全屏HTML 5適配 個人見解HTML
- C++ new用法的個人見解C++
- 【最短路徑Floyd演算法詳解推導過程】看完這篇,你還能不懂Floyd演算法?還不會?演算法
- 資料結構——Floyd演算法資料結構演算法
- Floyd演算法學習筆記演算法筆記
- [MATLAB]最短路徑Floyd演算法Matlab演算法
- Web快速開發平臺個人之淺見Web
- 最短路徑——Dijkstra演算法和Floyd演算法演算法
- 多源最短路徑演算法:Floyd演算法演算法
- Floyd演算法(計算最短路徑)演算法
- 關於 Laravel 的一些個人見解Laravel
- 求最短路徑——DFS+Floyd演算法演算法
- 和小哥哥一起刷洛谷(8) 圖論之Floyd“演算法”圖論演算法
- 21個JavaScript 面試中常見演算法問題詳解JavaScript面試演算法
- 淺談,C語言編譯原理的個人見解C語言編譯原理
- 最短路徑——floyd演算法程式碼(c語言)演算法C語言
- 錯誤程式碼的個人見解以及邏輯分析題
- Mac 下 Docker 執行較慢的原因分析及個人見解MacDocker
- POJ3660 Cow Contest【Floyd演算法 傳遞閉包】演算法
- 多源最短路徑,一文搞懂Floyd演算法演算法
- 最短路-Floyd
- 關於人工智慧技術應用場景的個人見解人工智慧
- 個人愚見:Redux 和 Mobx 區別Redux
- Laravel 個人開發常見問題Laravel
- 常見演算法技巧之——雙指標思想演算法指標
- Java常見排序演算法之插入排序Java排序演算法
- 最短路徑--dijkstra演算法、弗洛伊德(Floyd)演算法(帶路徑輸出)演算法
- 程式碼隨想錄演算法訓練營第64天 | 圖論:Floyd 演算法+A * 演算法演算法圖論
- 關於malloc原始碼中的bin_at巨集定義的個人見解原始碼