references
通常,我們發現沿著圖中的一條邊移動會有一些相關的成本(或利潤),例如邊的距離,汽油的**,花費的時間等等。
我們稱這之為加權圖,稱邊值為權值。
我們將之前的圖定義擴充套件如下:
加權圖g由有序序列(v, e, w)組成,其中v和e是頂點和邊,w是邊的權值。
w((a, b))=50, w((a, c))=30等等。
同時我們可以用圖的鄰接矩陣表示為:
「-」表示邊緣不存在。
與加權圖有關的乙個常見問題是尋找頂點之間的最短路徑。
該演算法的工作原理是將頂點分為兩個集合,s和c。
在每個迭代;s包含已經被選擇的節點集。
s也叫做選擇集 selected set.
在每個迭代;c包含了一組尚未被選中的節點:
c也叫做候選集 candidate set.
在每一步中,我們將到達c的最小節點移動到s。
我們還需要乙個函式d使d(ci)是我們目前找到的候選集合c中從頂點s到頂點ci的最短距離。
舉個例子:
我們現在選擇d的最小值,d(e)=10。
step 1:
我們將頂點e從c移動到s。
s=c=
d()= 20, 30, 50
a到d有兩條,一條為a-e-d:10+10=20,另一條是a-d=100,20<100所以我們不需要在d()中再加入100,後面出現這種情況同理。
我們現在選擇d的最小值,d(d)=20。
step 3:
將頂點c從c移動到s。
s=c=
d()= 35 // a-c-b 30+5=35
我們現在選擇d的最小值,d(b)=35
step 4:
將頂點b從c移動到s
s=c={}
c中沒有候選頂點了,所以我們完成了。
適用於具有負邊權值的圖。
識別負迴圈和路徑上有負迴圈的頂點。
為所有其他頂點找到正確的路徑和路徑長度。
舉個例子:
上圖中a-c-b組成了乙個迴圈,這個迴圈的總權值為-1,這意味著如果按照剛才dijkstra』s algorithm來的話,所有路徑都可以重複走這個cycle讓自己權值降到最低。
因此我們如何用bellman-ford考慮呢?
與dijkstra演算法不同的是,dijkstra演算法在每次迭代時只更新最有希望的(下乙個成本最低的)頂點,bellman-ford在每次迭代中更新每個頂點。
這意味著bellman-ford的每次迭代都比dijkstra的迭代需要更多的工作。
拿上圖舉例:
它有6個頂點,所以我們將在主迴圈中執行5次。
初始化:
我們為d設定初始值:
d(s)=0sa
bcde
0∞∞∞
∞∞迭代1:
頂點 s: 我們可以到達a和e, 更新。
頂點 a: 我們可以到達c, 更新。
頂點 b: 我們還不能到達,跳過。
頂點 c: 我們可以到達b, 更新。
頂點 d: 我們還不能到達,跳過。
頂點 e: 我們可以到達d, 更新。
下表為第一次迭代結束後的權值:sa
bcde
010101238
迭代2:
頂點 s: 我們可以到達a和e, 沒有變化。
頂點 a: 我們可以到達c, 沒有變化。
頂點 b: 我們可以到達a,更新
頂點 c: 我們可以到達b, 沒有變化。
頂點 d: 我們可以到達a和c,更新。
頂點 e: 我們可以到達d, 沒有變化。
下表為第二次迭代結束後的權值:sa
bcde
0-1102
38注意:a現在的權值是s-e-d-a=8-5-4=-1
c現在的權值是s-e-d-c=8-5-1=2
後面同理。
迭代3:
頂點 s: 我們可以到達a和e, 沒有變化。
頂點 a: 我們可以到達c, 更新。
頂點 b: 我們可以到達a,沒有變化。
頂點 c: 我們可以到達b, 更新。
頂點 d: 我們可以到達a和c,沒有變化。
頂點 e: 我們可以到達d, 沒有變化。
下表為第三次迭代結束後的權值:sa
bcde
0-1-11
38迭代4:
頂點 s: 我們可以到達a和e, 沒有變化。
頂點 a: 我們可以到達c, 沒有變化
頂點 b: 我們可以到達a,更新。
頂點 c: 我們可以到達b, 沒有變化。
頂點 d: 我們可以到達a和c,沒有變化。
頂點 e: 我們可以到達d, 沒有變化。
下表為第四次迭代結束後的權值:sa
bcde
0-2-11
38迭代5:
頂點 s: 我們可以到達a和e, 沒有變化。
頂點 a: 我們可以到達c, 更新。
頂點 b: 我們可以到達a,沒有變化。
頂點 c: 我們可以到達b, 更新。
頂點 d: 我們可以到達a和c,沒有變化。
頂點 e: 我們可以到達d, 沒有變化。
下表為第五次迭代結束後的權值:sa
bcde
0-2-20
38五次迭代結束,
檢查:頂點 s: 我們可以到達a和e, 沒有變化。
頂點 a: 我們可以到達c, 把a標記為bad。
頂點 b: 我們可以到達a,沒有變化。
頂點 c: 我們可以到達b, 沒有變化。
頂點 d: 我們可以到達a和c,沒有變化。
頂點 e: 我們可以到達d, 沒有變化。sa
bcde
0x-20
38結論:我們可以得出結論,圖包含乙個包含頂點a的負成本迴圈。
如果我們從頂點a開始執行dfs(或bfs),將所有訪問過的頂點標記為bad,我們得到以下結果:sa
bcde
0***
38因此:頂點 a: 通過迴圈到達。
頂點 b: 通過迴圈到達。
頂點 c: 通過迴圈到。
頂點 d: 可到達的花費為3。
頂點 e: 可到達的花費為8。
公式:f(n)=g(n)+h(n),
f(n) 是從初始狀態經由狀態n到目標狀態的代價估計。
g(n) 是在狀態空間中從初始狀態到狀態n的實際代價。
h(n) 是從狀態n到目標狀態的最佳路徑的估計代價。
放在路徑搜尋問題中,狀態就是圖中的節點,代價就是距離或者權重。
a*的訣竅是找到乙個好的啟發式。
對頂點選擇規則的啟發式修改將dijkstra演算法變成了乙個被稱為a*演算法的例子。
儘管在最壞的情況下,a*並不比dijkstra更快,但在實踐中,它通常代表著實質性的改進。
從v到g的估計最小路徑長度h(v, g)與實際最小路徑長度p(v, g)越接近,a*就越快找到解。
introduction to the design and analysis of algorithms, a. levitin, 3rd ed., pearson 2011.
introduction to algorithms, t. h. cormen, 3rd ed, mit press 2009.
資料結構之最短路徑(DijKstra)
dijkstra 迪傑斯特拉 演算法是典型的最短路徑路由演算法,用於計算乙個節點到其他所有節點的最短路徑。主要特點是以起始點為中心向外層層擴充套件,直到擴充套件到終點為止。dijkstra演算法能得出最短路徑的最優解,但由於它遍歷計算的節點很多,所以效率低。dijkstra演算法是很有代表性的最短路...
資料結構之最短路徑(Floyd)
floyd演算法,求網圖g中各頂點v到其餘頂點w的最短路徑p v w 及帶權長度d v w void shortestpath floyd mgraph g,patharc p,shortpathtable d 下面介紹下詳細的執行過程 1 程式開始執行,第4 11行就是初始化了d和p,使得它們成為...
資料結構之最短路徑問題
1.定義概覽 dijkstra 迪傑斯特拉 演算法是典型的單源最短路徑演算法,用於計算乙個節點到其他所有節點的最短路徑。主要特點是以起始點為中心向外層層擴充套件,直到擴充套件到終點為止。dijkstra演算法是很有代表性的最短路徑演算法,在很多專業課程中都作為基本內容有詳細的介紹,如資料結構,圖論,...