單源最短路徑的Bellman Ford演算法。

2021-06-29 01:19:22 字數 1428 閱讀 3107

本文主要講解求單源最短路徑的bellman-ford演算法。

bellman-ford演算法

bellman-ford演算法能夠在一般情況下,解決單源最短路徑問題。允許圖中出現權為負數的邊。該演算法還會返回乙個布林值。如果布林值為false,表示途中存在從源點可達的權為負的迴路。

首先介紹一下鬆弛計算。如下圖:

鬆弛計算之前,點b的值是8,但是點a的值加上邊上的權重2,得到5,比點b的值(8)小,所以,點b的值減小為5。這個過程的意義是,找到了一條通向b點更短的路線,且該路線是先經過點a,然後通過權重為2的邊,到達點b。

當然,如果 出現一下情況

則不會修改點b的值,因為3+4>6。

bellman-ford演算法可以大致分為三個部分

第一,初始化所有點。每乙個點儲存乙個值,表示從原點到達這個點的距離,將原點的值設為0,其它的點的值設為無窮大(表示不可達)。

第二,進行迴圈,迴圈下標為從1到n-1(n等於圖中點的個數)。在迴圈內部,遍歷所有的邊,進行鬆弛計算。

第三,遍歷途中所有的邊(edge(u,v)),判斷是否存在這樣情況:

d(v) > d (u) + w(u,v)

則返回false,表示途中存在從源點可達的權為負的迴路。

之所以需要第三部分的原因,是因為,如果存在從源點可達的權為負的迴路。則 應為無法收斂而導致不能求出最短路徑。

考慮如下的圖:

經過第一次遍歷後,點b的值變為5,點c的值變為8,這時,注意權重為-10的邊,這條邊的存在,導致點a的值變為-2。(8+ -10=-2)

第二次遍歷後,點b的值變為3,點c變為6,點a變為-4。正是因為有一條負邊在迴路中,導致每次遍歷後,各個點的值不斷變小。

在回過來看一下bellman-ford演算法的第三部分,遍歷所有邊,檢查是否存在d(v) > d (u) + w(u,v)。因為第二部分迴圈的次數是定長的,所以如果存在無法收斂的情況,則肯定能夠在第三部分中檢查出來。比如

此時,點a的值為-2,點b的值為5,邊ab的權重為5,5 > -2 + 5. 檢查出來這條邊沒有收斂。

所以,bellman-ford演算法可以解決圖中有權為負數的邊的單源最短路徑問。

單源最短路徑

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...