Dijkstra和Floyd演算法

2021-05-23 21:27:56 字數 1748 閱讀 3622

floyd演算法:

如果要求所有兩結點間的最短路徑,則可以使用dijkstra演算法n次完成,時間複雜度是

o(n^3),floyd還提出過另乙個演算法,同樣是o(n^3)的複雜度,但形式上更簡單些。

要求的解是乙個矩陣s[n][n],其中s[i][j]表示結點i到j的最短路徑,演算法很像動態

規劃演算法,甚至更簡單些,不同的是這裡規劃的是乙個矩陣,而不是簡單的陣列。

floyd演算法過程描述如下:

(在整個迴圈結束後,s[i][j]肯定是i和j之間的最短路徑——i如果和j之間有直接通路,但是比s[i][k]+s[k][j]長的話就會被s[i][k]+s[k][j]替換,而s[i][k](或s[k][j])可能也是中間經過某乙個其他點(這邊設為w點)而得到的i到k的最短路徑,所以可能i到j的最短路徑是由s[i][k]+s[k][j]得到,而s[i][k]又是由i到w再到k的(s[k][j]同理),因此i到j的最短路徑就可能是i—>w—>k—>j的(這邊假設s[k][j]中間沒有經過其他點,自己就是最短的))

1、 首先s以邊集m初始化,得到所有的直接連通代價;

2、 依次考慮第k個結點,對於s中的每乙個s[i][j],判斷是否滿足:

s[i][j]>s[i][k]+s[k][j],如果滿足則用s[i][k]+s[k][j]代替s[i][j],此為第k步;

3、 k迴圈取遍所有結點,演算法結束時,s為最終解。

這樣的求法自然再簡單不過了,但要證明其中的正確性,有些難度,為什麼不會使結點

重複存在於同一路徑?在替換的時候,s[i][k]和s[k][j]中如果同時含有m結點,則這樣的替

換顯然是錯誤的,相當於i-->m-->k-->m-->j,可以簡單用這有這樣連通關係的例子試一下,會

發現如果在一條路徑中有結點冗餘,則不可能是最短路徑,顯然上面這條有冗餘結點的路徑

肯定要比i-->m-->j要長,所以演算法在要求最短的同時已經排除了這種情況,這樣使得任意一

條路徑都不冗餘。

dijikstra演算法:

(dijkstra可以處理負權邊,不允許有負權環,否則可以通過不斷走負權環取得更小值。如果要考慮權值為負的情況可以用bellman-ford演算法來實現)

大體過程如下:(過程中涉及到乙個s集合用來儲存已經求出到源點的最短路徑的點,乙個u集合,儲存還沒有求出到源點最短路徑的點(即全部點的集合a減去集合s所得的集合))

1、  先將源點v加入s集合中;

2、  在剩下的u集合中找到與v有直接關聯的邊且其權值最小的點,先將該直接邊的權值作為該點暫時的最短路徑,將s集合裡面的各個點與這點關聯起來(如果有直接關聯的邊的話),看從源點v到該點(中間經過若干s集合中的點)的權值之和是不是小於v與該點間直接邊的權值,如果小於的話就替換該點的最短路徑;

3、  看u集合中還有沒有點,如果有的話則重複步驟2,否則演算法結束

注:在進行上述演算法前如果先對各個點之間的權值大小進行排序可以提高演算法效率,在步驟2中「在剩下的u集合中找到與v有直接關聯的邊且其權值最小的點」時可以不用每次都遍歷所有的邊。

再注:每一次向s中加入乙個點之後,對於u集合中的j點的原始最短路徑值(與源點有直接關聯邊的就是直接關聯邊的權值,沒有的話就是無窮大)的影響:如果有影響,那影響後的路徑肯定是先經過s集合中的某些點然後再經過剛剛加入s集合的點再直接到j點,而不可能是先經過s集合中的某些點再經過剛剛加入s集合的點,再經過s集合中的其他點(設為x點)再到j點的,因為如果是這樣的話那剛剛加入s集合的點(設為k點)應該在x之前就已經加入s集合了的,因為x在k之前加入s集合,所以vx的路徑長度肯定大於vkx的路徑長度,而後面加j的時候都是加上xj的長度,這個顯然不合理了的。

最短路 Floyd演算法和Dijkstra演算法

兩者在負權問題上不是很好,最好只處理正值,dijkstra演算法對負權毫無辦法,但是floyd演算法不能處理出現負環的東西。dijkstra演算法的話,為了方便,我認為從i到i點不可達 百部百科解釋挺好,那個堆優化挺好的 floyd演算法百部百科也不錯,都是老演算法了,哪都有資料 這位筒子的寫得很好...

Dijkstra和Floyd演算法

floyd 演算法 如果要求所有兩結點間的最短路徑,則可以使用 dijkstra演算法n 次完成,時間複雜度是 o n 3 floyd 還提出過另乙個演算法,同樣是 o n 3 的複雜度,但形式上更簡單些。要求的解是乙個矩陣 n n 其中s i j 表示結點i到 j的最短路徑,演算法很像動態 規劃演...

Floyd和Dijkstra演算法

floyd演算法 演算法解析 因為一張連通圖中不是所有點到其他點都是有一條直接路徑的,所以我們可以借助別的和終點相連的點到達終點,便是起點 中轉 終點 以小推大,小 假設當前只有1可以當中轉點,start為起點,end為終點 因此當start點需要借助點1到end點時,便需要進行if edge st...