Bellman Ford 演算法及其優化

2021-06-29 01:22:32 字數 2874 閱讀 9199

bellman-ford

演算法與另乙個非常著名的

dijkstra

演算法一樣,用於求解單源點最短路徑問題。

bellman-ford

演算法除了可求解邊權均非負的問題外,還可以解決存在負權邊的問題(意義是什麼,好好思考),而

dijkstra

演算法只能處理邊權非負的問題,因此

bellman-ford

演算法的適用面要廣泛一些。但是,原始的

bellman-ford

演算法時間複雜度為o(

ve),比

dijkstra

演算法的時間複雜度高,所以常常被眾多的大學演算法教科書所忽略,就連經典的《演算法導論》也只介紹了基本的

bellman-ford

演算法,在國內常見的基本資訊學奧賽教材中也均未提及,因此該演算法的知名度與被掌握度都不如

dijkstra

演算法。事實上,有多種形式的

bellman-ford

演算法的優化實現。這些優化實現在時間效率上得到相當提公升,例如近一兩年被熱捧的

spfa

(shortest-path faster algoithm

更快的最短路徑演算法)演算法的時間效率甚至由於

dijkstra

演算法,因此成為資訊學奧賽選手經常討論的話題。然而,限於資料匱乏,有關

bellman-ford

演算法的諸多問題常常困擾奧賽選手。如:該演算法值得掌握麼?怎樣用程式語言具體實現?有哪些優化?與

spfa

演算法有關係麼?本文試圖對

bellman-ford

演算法做乙個比較全面的介紹。給出幾種實現程式,從理論和實測兩方面分析他們的時間複雜度,供大家在備戰省選和後續的

noi時參考。

bellman-ford

演算法能在更普遍的情況下(存在負權邊)解決單源點最短路徑問題。對於給定的帶權(有向或無向)圖g=(

v,e),其源點為

s,加權函式w是

邊集e 

的對映。對圖g執行

bellman-ford

演算法的結果是乙個布林值,表明圖中是否存在著乙個從源點s

可達的負權迴路。若不存在這樣的迴路,演算法將給出從源點s到

圖g的任意頂點

v的最短路徑

d[v]

。(1)

初始化:將除源點外的所有頂點的最短距離估計值

d[v]

←+∞, d[s] ←0;

(2)迭代求解:反覆對邊集e中的每條邊進行鬆弛操作,使得頂點集v中的每個頂點v的最短距離估計值逐步逼近其最短距離;(執行|v|-1次)

(3)檢驗負權迴路:判斷邊集

e中的每一條邊的兩個端點是否收斂。如果存在未收斂的頂點,則演算法返回

false

,表明問題無解;否則演算法返回

true

,並且從源點可達的頂點

v的最短距離儲存在

d[v]中。

演算法描述如下:

bellman-ford(g,w,s) 

:boolean//圖g

,邊集函式w,

s為源點 1

foreachvertexv

∈ v(g) do//初始化1階段 2

d[v]

←+∞

3d[s] ←0;//1階段結束 4

fori=1to|v|-1do//2階段開始,雙重迴圈。 5

foreach edge(u,v) ∈e(g) do //邊集陣列要用到,窮舉每條邊。 6

if d[v]>d[u]+w(u,v)then//鬆弛判斷 7

d[v]=d[u]+w(u,v)//鬆弛操作2階段結束 8

foreach edge(u,v) ∈e(g) do 9

if d[v]>d[u]+w(u,v)then 10

exitfalse 11

exit true

下面給出描述性證明:

首先指出,圖的任意一條最短路徑既不能包含負權迴路,也不會包含正權迴路,因此它最多包含

|v|-1

條邊。

其次,從源點

s可達的所有頂點如果

存在最短路徑,則這些最短路徑構成乙個以

s為根的最短路徑樹。

bellman-ford演算法的迭代鬆弛操作,實際上就是按頂點距離s的層次,逐層生成這棵最短路徑樹的過程。

在對每條邊進行1遍鬆弛的時候,生成了從s出發,層次至多為1的那些樹枝。也就是說,找到了與s至多有1條邊相聯的那些頂點的最短路徑;對每條邊進行第2遍鬆弛的時候,生成了第2層次的樹枝,就是說找到了經過2條邊相連的那些頂點的最短路徑……。因為最短路徑最多隻包含|v|-1 條邊,所以,只需要迴圈|v|-1 次。

每實施一次鬆弛操作,最短路徑樹上就會有一層頂點達到其最短距離,此後這層頂點的最短距離值就會一直保持不變,不再受後續鬆弛操作的影響。(但是,每次還要判斷鬆弛,這裡浪費了大量的時間,怎麼優化?單純的優化是否可行?)

如果沒有負權迴路,由於最短路徑樹的高度最多只能是|v|-1,所以最多經過|v|-1遍鬆弛操作後,所有從s可達的頂點必將求出最短距離。如果 d[v]仍保持 +∞,則表明從s到v不可達。

如果有負權迴路,那麼第|v|-1 遍鬆弛操作仍然會成功,這時,負權回路上的頂點不會收斂。

例如對於上圖,邊上方框中的數字代表權值,頂點a,b,c之間存在負權迴路。s是源點,頂點中數字表示執行bellman-ford演算法後各點的最短距離估計值。

此時d[a]的值為1,大於d[c]+w(c,a)的值-2,由此d[a]可以鬆弛為-2,然後d[b]又可以鬆弛為-5,d[c]又可以鬆弛為-7.下乙個週期,d[a]又可以更新為更小的值,這個過程永遠不會終止。因此,在迭代求解最短路徑階段結束後,可以通過檢驗邊集e的每條邊(u,v)是否滿足關係式d[v]>d[u]+w(u,v)來判斷是否存在負權迴路。

Bellman Ford 演算法及其優化

bellman ford 演算法及其優化 bellman ford 演算法與另乙個非常著名的 dijkstra 演算法一樣,用於求解單源點最短路徑問題。bellman ford 演算法除了可求解邊權均非負的問題外,還可以解決存在負權邊的問題 意義是什麼,好好思考 而 dijkstra 演算法只能處理...

Bellman Ford演算法及其佇列優化與實戰入門

bellman ford演算法能解決負權邊的圖,就是說能夠來判斷存在負環。先來看一下核心 dis i 為源點到i點的最短路 for k 1 k n 1 k n為頂點的個數 for int i 1 i m i m為邊的條數 if dis v i dis u i w i u i 為第i條邊的起點,v i...

Bellman Ford演算法,SPFA演算法

bellman ford 演算法能在更普遍的情況下 存在負權邊 解決單源點最短路徑問題。對於給定的帶權 有向或無向 圖g v,e 其源點為 s,加權函式w是 邊集e 的對映。對圖g執行 bellman ford 演算法的結果是乙個布林值,表明圖中是否存在著乙個從源點s 可達的負權迴路。若不存在這樣的...