如何加快Dijkstra算法的運行速度?

在Dijkstra算法中,面對單源單目標的最短路徑,若是遇到了要relax的節點u就是目標節點t,顯然就能夠執行結束了。算法

Dijkstra算法post

Dijkstra算法的探索路徑是從源一直往目標前景,那麼加速它的一個角度就是從源開始探索的時候,同時從目標點向源開始探索,這種算法即Bi-Directional Search。.net

Bi-Directional Search

具體操做位,從源點和從目標兩個方向均開始搜索,輪流的執行。兩個方向的搜索意味着,在初始化的時候將有兩個路徑值:d_f[u]:向前搜索最短路徑、d_b[u]向後搜索最短路徑;兩個最小優先級隊列 Q_fQ_b;對應的前一個節點指向 \pi_f\pi_b;以及S_fS_b3d

  • 向前搜索:沿着源點向目標搜索
  • 向後搜索:沿着目標向源點搜索

Bi-Directional Search的結束條件是什麼?

對於選出的頂點u,當他'同時'被前向搜索和後向搜索處理完成,或者說是‘同時’從Q_fQ_b中刪除了,此時能夠結束。指針

當 Bi-Directional Search的結束的時候,如何找到最短路徑?

可能想到的思路是,若是u是第一個知足結束條件的,那麼沿着各自的前向指針,便可找到最短路徑。以以下搜索爲例:code

向前搜索:從源點出發,使用Dijkstra算法,能夠計算出 Q_f={a(3),u(5),b( \infty),t( \infty)}, S_f={s(0)}

向後搜索:從目標出發,使用Dijkstra算法,能夠計算出 Q_b={a( \infty),s( \infty),b(3),u(5)}, S_b={t(0)}

向前搜索:從Q_f中移除的最小值爲 d_f[a]=3,執行邊(a,b)的Relax操做,可獲得Q_f={u(5),b(6),t(\infty)},S_f={s(0),a(3)}cdn

向後搜索:從 Q_b中移除最小值爲 d_b[b]=3,執行邊(a,b)的Relax操做,能夠計算出 Q_b={a(6),s( \infty),u(5)}, S_b={t(0),b(3)}

向前搜索:從Q_f中移除的最小值爲 d_f[u]=5,執行邊(u,t)的Relax操做,可獲得Q_f={b(6),t(10)},S_f={s(0),a(3),u(5)}blog

向後搜索:從 Q_b中移除最小值爲 d_b[u]=5,執行邊(s,u)的Relax操做,能夠計算出 Q_b={a(6),s(10)}, S_b={t(0),b(3),u(5)}

此時的u達到了終止的條件,同時從 Q_fQ_b中刪除,按照前向搜索和後向搜索的指針去計算最短路徑,發現爲10,很明顯不是最短路徑。
正確的計算方式爲:當終止以後,應該找到一個頂點x,使得 d_f[x]+ d_b[x]最小。具體措施爲,看 S_fQ_f中的全部節點,看它在 S_bQ_b中值,使得 d_f[x]+ d_b[x]最小

另外一種算法爲Goal-Directed Search ,詳見 www.researchgate.net/publication…隊列

附錄

算法導論(MIT 6.006 第18講)get

相關文章
相關標籤/搜索