求單源最短路徑的算法(Bellman-Ford)

本文主要講解求單源最短路徑的BellmanFord算法。

BellmanFord算法

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

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

 

<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" /><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

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

當然,如果 出現一下情況

 

則不會修改點B的值,因爲34>6

 

BellmanFord算法可以大致分爲三個部分

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

第二,進行循環,循環下標爲從1n1n等於圖中點的個數)。在循環內部,遍歷所有的邊,進行鬆弛計算。

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

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

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

 

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

考慮如下的圖:

 

經過第一次遍歷後,點B的值變爲5,點C的值變爲8,這時,注意權重爲-10的邊,這條邊的存在,導致點A的值變爲-2。(8 10=-2

 

 

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

 

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

 

此時,點A的值爲-2,點B的值爲5,邊AB的權重爲55 > -2 + 5. 檢查出來這條邊沒有收斂。

 

所以,BellmanFord算法可以解決圖中有權爲負數的邊的單源最短路徑問。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章