1. 程式人生 > >幾個最短路徑演算法Floyd、Dijkstra、Bellman-Ford、SPFA的比較

幾個最短路徑演算法Floyd、Dijkstra、Bellman-Ford、SPFA的比較

      幾大最短路徑演算法比較

July、二零一一年二月十二日。
----------------------------------- 

幾個最短路徑演算法的比較:
Floyd

求多源、無負權邊的最短路。用矩陣記錄圖。時效性較差,時間複雜度O(V^3)。
       Floyd-Warshall演算法(Floyd-Warshall algorithm)是解決任意兩點間的最短路徑的一種演算法,可以正確處理有向圖或負權的最短路徑問題。

Floyd-Warshall演算法的時間複雜度為O(N^3),空間複雜度為O(N^2)。

      Floyd-Warshall的原理是動態規劃:
設Di,j,k為從i到j的只以(1..k)集合中的節點為中間節點的最短路徑的長度。
若最短路徑經過點k,則Di,j,k = Di,k,k-1 + Dk,j,k-1;
若最短路徑不經過點k,則Di,j,k = Di,j,k-1。
因此,Di,j,k = min(Di,k,k-1 + Dk,j,k-1 , Di,j,k-1)。

      在實際演算法中,為了節約空間,可以直接在原來空間上進行迭代,這樣空間可降至二維。
Floyd-Warshall演算法的描述如下:
for k ← 1 to n do
  for i ← 1 to n do
    for j ← 1 to n do
      if (Di,k + Dk,j < Di,j) then
        Di,j ← Di,k + Dk,j;
其中Di,j表示由點i到點j的代價,當Di,j為 ∞ 表示兩點之間沒有任何連線。

Dijkstra

      求單源、無負權的最短路。時效性較好,時間複雜度為O(V*V+E)。
源點可達的話,O(V*lgV+E*lgV)=>O(E*lgV)。
      當是稀疏圖的情況時,此時E=V*V/lgV,所以演算法的時間複雜度可為O(V^2)

。若是斐波那契堆作優先佇列的話,演算法時間複雜度,則為O(V*lgV + E)。

Bellman-Ford

      求單源最短路,可以判斷有無負權迴路(若有,則不存在最短路),
時效性較好,時間複雜度O(VE)。此演算法日後還會在本BLOG內具體闡述

Bellman-Ford演算法是求解單源最短路徑問題的一種演算法。

      單源點的最短路徑問題是指:
給定一個加權有向圖G和源點s,對於圖G中的任意一點v,求從s到v的最短路徑。

      與Dijkstra演算法不同的是,在Bellman-Ford演算法中,邊的權值可以為負數。
      設想從我們可以從圖中找到一個環路(即從v出發,經過若干個點之後又回到v)且這個環路中所有邊的權值之和為負。那麼通過這個環路,環路中任意兩點的最短路徑就可以無窮小下去。如果不處理這個負環路,程式就會永遠執行下去。 而Bellman-Ford演算法具有分辨這種負環路的能力。


SPFA

      是Bellman-Ford的佇列優化,時效性相對好,時間複雜度O(kE)。(k<<V)。

與Bellman-ford演算法類似,SPFA演算法採用一系列的鬆弛操作以得到從某一個節點出發到達圖中其它所有節點的最短路徑。所不同的是,SPFA演算法通過維護一個佇列,使得一個節點的當前最短路徑被更新之後沒有必要立刻去更新其他的節點,從而大大減少了重複的操作次數。

      SPFA演算法可以用於存在負數邊權的圖,這與dijkstra演算法是不同的。

與Dijkstra演算法與Bellman-ford演算法不同,SPFA的演算法時間效率是不穩定的,即它對於不同的圖所需要的時間有很大的差別。

      在最好情形下,每一個節點都只入隊一次,則演算法實際上變為廣度優先遍歷,其時間複雜度僅為O(E)。另一方面,存在這樣的例子,使得每一個節點都被入隊(V-1)次,此時演算法退化為Bellman-ford演算法,其時間複雜度為O(VE)。

      SPFA演算法在負邊權圖上可以完全取代Bellman-ford演算法,另外在稀疏圖中也表現良好。但是在非負邊權圖中,為了避免最壞情況的出現,通常使用效率更加穩定的Dijkstra演算法,以及它的使用堆優化的版本。通常的SPFA演算法在一類網格圖中的表現不盡如人意。

完。

相關推薦

路徑演算法FloydDijkstraBellman-FordSPFA比較

      幾大最短路徑演算法比較July、二零一一年二月十二日。----------------------------------- 幾個最短路徑演算法的比較:Floyd求多源、無負權邊的最短路。用矩陣記錄圖。時效性較差,時間複雜度O(V^3)。       Floyd-

路徑演算法Floyd(弗洛伊德)演算法分析與實現(Python)

December 19, 2015 10:56 PM Floyd演算法是解決任意兩點間的最短路徑的一種演算法,可以正確處理帶權有向圖或負權的最短路徑問題 解決此問題有兩種方法: 其一是分別以圖中每個頂點為源點共呼叫n次演算法; 其二是採用Floyd演算法

多源路徑演算法---Floyd-Warshall

暑假,小哼準備去一些城市旅遊。有些城市之間有公路,有些城市之間則沒有,如下圖。為了節省經費以及方便計劃旅程,小哼希望在出發之前知道任意兩個城市之前的最短路程。 上圖中有4個城市8條公路,公路上的數字表示這條公路的長短。請注意這些公路是單向的。我們現在需要求任意兩

路徑演算法Floyd(弗洛伊德)演算法

Floyd演算法(解決任意兩點間的最短路徑,可以正確處理有向圖或負權值的最短路徑問題): 時間複雜度O(N3),空間複雜度O(N2); 演算法思想: Floyd演算法是一個經典的動態規劃演算法;首先我

短路演算法Floyed, DijkstraBellman-FordSPFA

Floyed演算法,複雜度o(n^3); 更新i->j的距離,通過中介點k,如果能夠通過k使得i->j的距離更短,那麼更新。 程式碼 void Folyed() { for (int k = 0; k < n; k++) { for (int i = 0

(路徑演算法整理)dijkstrafloydbellman-fordspfa演算法模板的整理與介紹

 這一篇部落格以一些OJ上的題目為載體,整理一下最短路徑演算法。會陸續的更新。。。一、多源最短路演算法——floyd演算法       floyd演算法主要用於求任意兩點間的最短路徑,也成最短最短路徑問

小生成樹(prime演算法kruskal演算法) 和 路徑演算法floyddijkstra

簡介: 帶權圖分為有向和無向,無向圖的最短路徑又叫做最小生成樹,有prime演算法和kruskal演算法;有向圖的最短路徑演算法有dijkstra演算法和floyd演算法。   生成樹

(路徑算法整理)dijkstrafloydbellman-fordspfa算法模板的整理與介紹

void empty borde fast 默認 grand else 理解 scan 這一篇博客以一些OJ上的題目為載體。整理一下最短路徑算法。會陸續的更新。。。 一、多源最短路算法——floyd算法 floyd算法主要用於求隨意兩點間的最短路徑。也成

Floyd路徑演算法

使用帶權圖的鄰接矩陣方法表示圖並且不能有負週期。如: g = [ [0,1,float('inf'),1,5], [9,0,3,2,float('inf')], [float('inf'),float('inf'),0,4,float('

資料結構與演算法--路徑Floyd演算法

  一、解決單源最短路徑問題的Dijkstra演算法      我們知道Dijkstra演算法只能解決單源最短路徑問題,且要求邊上的權重都是非負的。那麼有沒有辦法解決任意起點到任意頂點的最短路徑問題呢?如果用Dijkstra演算法,可以這樣做: Dijkstra[]

Floyd-Warshall 所有結點對的路徑演算法

以下程式碼僅支援結點是順序的,比如輸入5個結點,結點的編號只能是1到5,輸入順序可以不一致。 動態規劃真的簡潔,三個 for 把這麼複雜的東西就整理好了。 遞推公式:**d[i][j] = min ( d[i][j] , d[i][k] + d[k][j] )

路徑問題---Floyd演算法詳解

前言 Genius only means hard-working all one’s life. Name:Willam Time:2017/3/8 1、最短路徑問題介紹 問題解釋: 從圖中的某個頂點出發到達另外一個頂點的所經過的邊的權重和最

路徑演算法 Dijkstra演算法 Floyd演算法 簡述

Dijkstra演算法 又稱迪傑斯特拉演算法,是一個經典的最短路徑演算法,主要特點是以起始點為中心向外層層擴充套件,直到擴充套件到終點為止,使用了廣度優先搜尋解決賦權有向圖的單源最短路徑問題,演算法最終得到一個最短路徑樹。時間複雜度為O(N^2) 執行動畫: 例項:

路徑演算法比較DijkstraBellman-FordSPFA)及實現(Java)

Bellman-Ford(Java) package com; import java.util.Scanner; public class Bellman_Ford { private static E edge[]; private static int

圖的路徑演算法(DijkstraFloyd)的實現

從某個源點到其餘各頂點的最短路徑 迪杰特斯拉演算法 Dijkstra(迪傑斯特拉)演算法是典型的單源最短路徑演算法,用於計算一個節點到其他所有節點的最短路徑。主要特點是以起始點為中心向外層層擴充套件,直到擴充套件到終點為止。 演算法步驟如下:

DijkstraFloyd演算法----路徑演算法

Dijkstra 轉自:http://blog.chinaunix.net/uid-26548237-id-3834514.html Dijkstra(迪傑斯特拉)演算法是典型的最短路徑路由演算法,用於計算一個節點到其他所有節點的最短路徑。主要特點是以起始點為中心向外

C++ dijkstra 路徑演算法top排序DFSBFS 示例 C++11

好一段時間前寫的了。。。正好現在在複習資料結構,重構了一下程式碼 首先先是 圖、點Vertex和邊AdjACent的定義 class JpGraph { public: class Vertex; class

有向圖的路徑Floyd演算法

最近在研究最短路徑演算法,使用java實現。 原始資料是一共有6個點,他們之中任意2個點(i,j)之間的距離v(i,j)的數值如下面二位陣列中所示,整體演算法使用Java語言實現。 class Floyd{ public static void main(S

MIT演算法導論公開課之第18課 路徑演算法Bellman和差分約束系統

Bellman-Ford 演算法 圖G=(V,E),選取s∈V作為圖的原點,此演算法可計算最短路徑δ(s,v)(v∈V)或報告出圖中存在負權值的環路。 Exercise 在路徑中存在負權值的環路時,將δ(s,v)設定為-∞。 Bellman-F

任意兩點之間的路徑問題(Floyd-Warshall演算法)

求解所有兩點之間的最短路問題叫做任意兩點之間的最短路問題。Floyd-Warshall演算法考慮的是 一條最短路徑上的中間結點。例如,簡單路徑p={v1,v2,...vl}上的中間結點指的是路徑p上除