我剛剛閱讀了使用雙向搜索的最短路徑Dijkstra算法的NetworkX實現(位於this)。這種方法的終止點是什麼?NetworkX的「Bidirectional Dijkstra」
回答
我將基於networkx的實現。
雙向Dijkstra在兩個方向上遇到相同節點時停止 - 但它在該點返回的路徑可能不通過該節點。它正在進行額外的計算以追蹤最短路徑的最佳候選者。
我要立足於您的評論我的解釋(上this answer)
考慮一個簡單的圖形(與節點A,B,C,d,E)。該圖的邊緣及其權重爲:「A-> B:1」,「A-> C:6」,「A-> D:4」,「A-> E:10」,「D-> C:3" , 「C-> E:1」。當我在這個圖的兩邊使用Dijkstra算法時:在前面它找到B在A之後,然後D在後面找到C在E之後,然後D.在這一點上,兩個集合具有相同的頂點和交點。這是終止點還是必須繼續?因爲這個答案(A-> D-> C-> E)不正確。
當我運行在反的(非定向)網絡上networkx的雙向Dijkstra算法,你聲稱評論:"A->B:1","A->C:6","A->D:4","A->E:10","D->C:3","C->E:1"
:它給了我:(7, ['A', 'C', 'E'])
,不A-D-C-E
。
問題是在誤解它在做什麼之前它停止。它在搜索節點方面完全符合你的期望,但是當它這樣做時,會發生額外的處理以找到最短路徑。當它從兩個方向到達D
時,它已經收集了一些可能更短的其他「候選」路徑。不能保證僅僅是因爲從兩個方向到達節點D
,最終成爲最短路徑的一部分。相反,在從兩個方向到達節點的點上,當前候選最短路徑比它繼續運行時將找到的任何候選路徑更短。
該算法有兩個空簇開始,每個A
或E
{} {}
相關聯,它會建立「集羣」圍繞每個。它首先把A
與A
{A:0} {}
相關的集羣現在,它會檢查是否A
已經在集羣E
在(目前爲空)。不是這樣。接下來,它查看每個鄰居A
並檢查它們是否在E
附近的集羣中。他們不是。然後它將所有這些鄰居放入一個堆(如有序列表)中,即A
即將到來的鄰居A
的路徑長度。稱此爲的A
clusters ..... fringes
{A:0} {} ..... A:[(B,1), (D,4), (C,6), (E,10)]
E:[]
現在檢查E
'邊緣'。對於E
它做對稱的事情。將E
放置到其集羣中。檢查E
不在A
附近的羣集中。然後檢查它的所有鄰居,看看是否有任何在A
附近的羣集(他們不是)。然後創建E
的邊緣。
clusters fringes
{A:0} {E:0} ..... A:[(B,1), (D,4), (C,6), (E,10)]
E:[(C,1), (A,10)]
現在它回到A
。從列表中取出B
,並將其添加到集羣A
左右。它檢查B
的任何鄰居是否在圍繞E
的簇中(沒有鄰居要考慮)。因此,我們有:
clusters fringes
{A:0, B:1} {E:0} ..... A:[(D,4), (C,6), (E,10)]
E:[(C,1), (A,10)]
返回E
:我們添加C
托特他集羣E
和檢查C
任何鄰居是否是A
在羣集中。你知道什麼,有A
。所以我們有一個候選人最短路徑A-C-E,距離爲7.我們將繼續這樣做。我們增加D
添加到邊緣E
(距離4,因爲它是1 + 3)。我們有:
clusters fringes
{A:0, B:1} {E:0, C:1} ..... A:[(D,4), (C,6), (E,10)]
E:[(D,4), (A,10)]
candidate path: A-C-E, length 7
返回A
:我們從它的邊緣,D
獲得接下來的事情。我們將其添加到集羣約A
,並注意其鄰居C
是在集羣約E
。所以我們有一個新的候選路徑,A-D-C-E
,但它的長度大於7,所以我們放棄它。
clusters fringes
{A:0, B:1, D:4} {E:0, C:1} ..... A:[(C,6), (E,10)]
E:[(D,4), (A,10)]
candidate path: A-C-E, length 7
現在我們回到E
。我們看看D
。它位於A
附近的羣集中。我們可以肯定的是,我們將遇到的任何未來候選人路徑的長度至少與我們剛剛查明的A-D-C-E
路徑一樣大(這種說法不一定很明顯,但它是這種方法的關鍵)。所以我們可以停止。我們返回前面找到的候選路徑。
- 1. Dijkstra的算法與Networkx的實現,顯示打印錯誤
- 2. C++ STL-like Bidirectional Multimap
- 3. @PrimaryKeyJoinColumn與Bidirectional @OneToOne關係
- 4. Parallel Dijkstra
- 5. 從NetworkX
- 6. 在networkx
- 7. easy_install networkx
- 8. 與networkx
- 9. 在networkx
- 10. Python,networkx
- 11. networkx convert_node_labels_to_integers
- 12. Dijkstra的三座標
- 13. TLE在codeforces的Dijkstra
- 14. Python - Dijkstra的算法
- 15. Dijkstra的algorthm修飾
- 16. Python:在NetworkX中着色特定邊緣
- 17. Dijkstra環狀樹
- 18. Python Dijkstra算法
- 19. Dijkstra或TSP
- 20. 關於Dijkstra omp
- 21. Dijkstra在Prolog
- 22. Dijkstra重構圖
- 23. Dijkstra遞歸java.lang.StackOverflowError
- 24. Dijkstra算法
- 25. Dijkstra算法C
- 26. Dijkstra和FileInput。 Java
- 27. BiDirectional Key to <-> GAE中的「CompositKey」查找?
- 28. get_edge_attribute返回networkx
- 29. Networkx Multigraph from_pandas_dataframe
- 30. datacursormode for networkx
在其代碼中的一條評論中說:'#如果我們已經在兩個方向上掃描了v,我們已經完成#我們現在已經發現了最短路徑。但是我們在[這篇文章]有一個反例(http://cs.stackexchange.com/questions/53943/is-the-bidirectional-dijkstra-algorithm-optimal) – moksef
對於它的價值 - 在這個例子中你給了networkx給出正確的路徑。 – Joel
@Joel謝謝你的確切答案。你能否提供更多的細節,比如你的測試程序或者跟蹤它。 – moksef