[英]A BFS Algorithm for Weighted Graphs - To Find Shortest Distance
我已經看過很多關於這個主題的帖子(即post1 、 post2 、 post3 ),但沒有一個帖子提供了備份相應查詢的算法。 因此,我不確定接受這些帖子的答案。
在這里,我提出了一種基於 BFS 的最短路徑(單源)算法,該算法適用於非負加權圖。 任何人都可以幫助我理解為什么 BFS(根據以下基於 BFS 的算法)不用於此類問題(涉及加權圖)!
算法:
SingleSourceShortestPath (G, w, s):
//G is graph, w is weight function, s is source vertex
//assume each vertex has 'col' (color), 'd' (distance), and 'p' (predecessor)
properties
Initialize all vertext's color to WHITE, distance to INFINITY (or a large number
larger than any edge's weight, and predecessor to NIL
Q:= initialize an empty queue
s.d=0
s.col=GREY //invariant, only GREY vertex goes inside the Q
Q.enqueue(s) //enqueue 's' to Q
while Q is not empty
u = Q.dequeue() //dequeue in FIFO manner
for each vertex v in adj[u] //adj[u] provides adjacency list of u
if v is WHITE or GREY //candidate for distance update
if u.d + w(u,v) < v.d //w(u,v) gives weight of the
//edge from u to v
v.d=u.d + w(u,v)
v.p=u
if v is WHITE
v.col=GREY //invariant, only GREY in Q
Q.enqueue(v)
end-if
end-if
end-if
end-for
u.col=BLACK //invariant, don't update any field of BLACK vertex.
// i.e. 'd' field is sealed
end-while
運行時:據我所知它是 O(|V| + |E|) 包括初始化成本
如果此算法類似於任何現有算法,請告訴我
由於偽代碼是帶有 FIFO 隊列的 Dijksta 算法,而不是始終根據距離排序的優先級隊列。 到目前為止,每個訪問過的(黑色)頂點已經計算出可能的最短距離的關鍵不變量不一定是真的。 這就是為什么優先隊列是計算(正)加權圖中距離的必要條件的原因。
您可以將算法用於未加權的圖,或者通過將權重為n
每條邊替換為由權重n-1
的邊連接的n-1
頂點來使其不加權。
反例:
第一個Q.enqueue(s)
之后的計算狀態:
第一次迭代后的計算狀態:
該圖作為反例的重要之處在於adj[u] = adj[S] = [F, M]
而不是[M, F]
,因此F
首先由Q.enqueue(v)
排隊
第二次迭代后的計算狀態:
由於頂點F
首先通過u = Q.dequeue()
出隊(與使用距離優先隊列時不同),因此此迭代不會更新任何距離, F
將變為黑色並且不變量將被違反。
最后一次迭代后的計算狀態:
我曾經也有同樣的困惑。 查看SPFA算法。 當作者早在 1994 年發表這個算法時,他聲稱它比具有 O(E) 復雜度的 Dijkstra 具有更好的性能,這是錯誤的。
您可以將此算法視為 Bellman-Ford 的變體/改進。 最壞情況的復雜度仍然是 O(VE),因為一個節點可能會多次從隊列中添加/刪除。 但是對於隨機稀疏圖,它絕對優於原始的 Bellman-Ford,因為它跳過了許多不必要的放松步驟。
盡管“SPFA”這個名字在學術界似乎並不被廣泛接受,但由於它的簡單和易於實施,它一經發布就在 ACM 學生中非常受歡迎。 性能明智的 Dijkstra 是首選。
看起來你實現了 Dijkstra 的經典算法,沒有堆。 您正在通過每個邊緣瀏覽矩陣,然后查看是否可以改善距離。
通常人們會在沒有邊緣權重時說它是 BFS。
BFS :具有恆定邊權重的圖。
Dijkstra :帶有邊權重的圖(可以處理一些負邊,如果
它沒有負循環)
Bellman-ford 和SPFA :負循環圖。
你的代碼是Dijkastra或SPFA變異,而不是一個簡單的BFS(雖然它是基於基於BFS alrorithm)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.