單源最短路徑(2) Bellman Ford 演算法

2022-01-10 13:34:46 字數 2301 閱讀 1380

dijkstra 演算法是處理單源最短路徑的有效演算法,但它對存在負權迴路的圖就會失效。這時候,就需要使用其他的演算法來應對這個問題,bellman-ford(中文名:貝爾曼-福特)演算法就是其中乙個。

bellman-ford 演算法不僅可以求出最短路徑,也可以檢測負權迴路的問題。該演算法由美國數學家理查德•貝爾曼(richard bellman, 動態規劃的提出者)和小萊斯特•福特(lester ford)發明。

對於乙個不存在負權迴路的圖,bellman-ford 演算法求解最短路徑的方法如下:

設其頂點數為 n,邊數為 m。設其源點為 source,陣列dist[i]記錄從源點 source 到頂點i的最短路徑,除了dist[source]初始化為 0 外,其它dist皆初始化為 int_max。以下操作迴圈執行 n-1 次:

n-1 次迴圈,bellman-ford 演算法就是利用已經找到的最短路徑去更新其它點的dist

接下來再看看 bellman-ford 演算法是如何檢測負權迴路的?

檢測的方法很簡單,只需在求解最短路徑的 n-1 次迴圈基礎上,再進行第 n 次迴圈:

迴圈次數

dist[0]

dist[1]

dist[2]

第1次0

-5-3

第2次-2

-5-3

第3次-2

-7-5

#include #include using namespace std;

struct edge

;edge edge[10000]; // 記錄所有邊

int dist[100]; // 源點到頂點 i 的最短距離

int path[100]; // 記錄最短路的路徑

int vertex_num; // 頂點數

int edge_num; // 邊數

int source; // 源點

bool bellmanford()

} }bool flag = true; // 標記是否有負權迴路

// 第 n 次迴圈判斷負權迴路

for (int i = 0; i < edge_num; i++) }

return flag;

}void print()

cout << "--" << source << endl;

} }}int main()

測試如下:

/* test 1 */

請輸入圖的頂點數,邊數,源點:5 7 0

請輸入 7 條邊的資訊:

0 1 100

0 2 30

0 4 10

2 1 60

2 3 60

3 1 10

4 3 50

0 到 1 的最短距離是:70,路徑是:1--3--4--0

0 到 2 的最短距離是:30,路徑是:2--0

0 到 3 的最短距離是:60,路徑是:3--4--0

0 到 4 的最短距離是:10,路徑是:4--0

/* test 2 */

請輸入圖的頂點數,邊數,源點:4 6 0

請輸入 6 條邊的資訊:

0 1 20

0 2 5

3 0 -200

1 3 4

3 1 4

2 3 2

存在負權迴路!

以下除非特殊說明,否則都預設是不存在負權迴路的。

先來看看 bellman-ford 演算法為何需要迴圈 n-1 次來求解最短路徑?

讀者可以從 dijkstra 演算法來考慮,想一下,dijkstra 從源點開始,更新dist,找到最小值,再更新dist,,,每次迴圈都可以確定至少乙個點的最短路。bellman-ford 演算法同樣也是這樣,它的每次迴圈也可以確定至少乙個點的最短路,故需要 n-1 次迴圈。

bellman-ford 演算法的時間複雜度為 \(o(nm)\),其中 n 為頂點數,m 為邊數。每一次迴圈都需要對 m 條邊進行操作,\(o(nm)\) 的時間,其實大多數都浪費了。

大家可以考慮乙個隨機圖(點和邊隨機生成),除了已確定最短路的頂點與尚未確定最短路的頂點之間的邊,其它的邊所做的都是無用的,大致描述為下圖(分割線以左為已確定最短路的頂點),

其中紅色部分為所做無用的邊,藍色部分為實際有用的邊。

既然只需用到中間藍色部分的邊,那演算法優化的方向就找到了,請接著看本系列第三篇文章:spfa 演算法。

單源最短路徑

include define max 999 define maxverts 10 typedef struct graph void chushi graph g void dij graph int key,int int int main for i 1 i g.numverts i dij ...

單源最短路徑

最優子結構 最短路徑的子路徑也是最短路徑,動態規劃和貪心演算法的乙個重要指標。環路 一條最短路徑不可能包含環路 1 環路權重為負,如果有一條環路權重為負,則不存在最短路徑 2 環路權重為零,如果包含該環路,則將該環路去掉即可 3 環路權重為正,去掉改環路可以得到更短的路徑,因此不可能是最短路徑 最短...

單源最短路徑

單源最短路徑問題,即在圖中求出給定頂點到其他任一頂點的最短路徑。1.最短路徑的最優子結構性質 該性質描述為 如果p i,j 是從頂點i到j的最短路徑,k和s是這條路徑上的乙個中間頂點,那麼p k,s 必定是從k到s的最短路徑。證明 假設p i,j 是從頂點i到j的最短路徑,則有p i,j p i,k...