我最近將Dijkstra算法的第三版本添加到我的項目中,以獲得最短路徑的單一源代碼。什麼是你知道的最快的Dijkstra實現(用C++)?
我意識到有很多不同的實現在性能上有很大的不同,而且在大圖中結果的質量也會有所不同。使用我的數據集(> 100.000個頂點),運行時間從20分鐘到幾秒不等。最短路徑也相差1-2%。
哪一個是你認識的最好的實現?
編輯: 我的數據是一個液壓網絡,每個節點有1到5個頂點。它可媲美街道地圖。我對已經加速的算法進行了一些修改(對所有剩餘的節點使用排序列表),現在可以在一小部分時間內找到相同的結果。我已經搜索了這樣的事情很長一段時間。我想知道這樣的實現是否已經存在。
我無法解釋結果中的細微差異。我知道Dijkstra不是啓發式的,但所有的實現似乎都是正確的。較快的解決方案具有較短路徑的結果。我專門使用雙精度數學。
編輯2: 我發現找到的路徑的差異確實是我的錯。我爲某些頂點插入了特殊處理(僅在一個方向上有效),並在其他實現中忘記了這一點。
但 IM仍然比嚇一跳的是Dijkstra算法可以通過下列變化顯着加速: 一般而言,Dijkstra算法包含了像一個循環:
MyListType toDoList; // List sorted by smallest distance
InsertAllNodes(toDoList);
while(! toDoList.empty())
{
MyNodeType *node = *toDoList.first();
toDoList.erase(toDoList.first());
...
}
如果你改變了這點,它工作原理相同,但性能更好:
MyListType toDoList; // List sorted by smallest distance
toDoList.insert(startNode);
while(! toDoList.empty())
{
MyNodeType *node = *toDoList.first();
toDoList.erase(toDoList.first());
for(MyNeigborType *x = node.Neigbors; x != NULL; x++)
{
...
toDoList.insert(x->Node);
}
}
看來,這種修改減少了不是大小的順序運行,但指數的順序。它將我的運行時窗體縮短爲30秒,小於2.在任何文獻中找不到此修改。這也很清楚,原因在於排序列表。插入/擦除的表現要差得多,因爲有100000個元素可以滿足要求。
答:
很多谷歌上搜索,我發現我自己的了。答案很清楚: boost graph lib。令人驚歎的 - 我還沒有發現這一段時間。如果您認爲Dijkstra實現之間沒有性能差異,請參閱wikipedia。
我的一個朋友可以在3分鐘內用C++實現Dijkstra。我還沒有聽說過任何更快的實施。 – jbasko 2009-06-02 07:39:55
我建議你可能想檢查那些實現......如果它們是正確的,它們應該都返回相同的最短路徑... Dijkstra的算法不是啓發式的... – jerryjvl 2009-06-02 07:45:28
最短路徑的差異可能是使用雙精度數學時,由於求和長序列的雙精度時的舍入誤差。不同的求和順序可能會產生不同的錯誤。你能測試你的整數實現嗎? – 2009-06-02 08:22:15