戴克斯特拉演算法計算工具
這是能逐步追蹤戴克斯特拉演算法如何在加權圖中求出從起點到各頂點最短路徑的工具。修改邊與權重的清單後,圖與步驟表會立即更新。可以用與考題相同形式的表格,確認汽車導航路徑搜尋與網路路由(OSPF)背後的基本概念。
結果
- 最短距離
- –
- 最短路徑
- –
本步確定的頂點 已確定 本步的更新 最短路徑
步驟表
每一步確定的頂點(上色)與當時到各頂點的距離。括號內為前一個頂點,紅字為該步更新的距離,已確定的頂點則留白。
到所有頂點的最短距離:
若有權重為負的邊,戴克斯特拉演算法可能得不到正確答案,因此權重限定為 0 以上。有多個距離相同的頂點時,依名稱順序先確定排在前面的頂點。同兩點之間有多條邊時,使用權重較小的那一條。
以圖表檢視
其他輸入維持目前的值,只讓選擇的輸入在目前值的 1/4 到 4 倍之間變化時的結果。紅點是目前的值。
戴克斯特拉演算法的步驟
戴克斯特拉演算法是在邊帶有 0 以上權重(距離、時間、費用)的圖中,求出從一個起點到所有頂點最短距離的方法。首先把起點的距離設為 0,其他頂點設為 ∞。接著從尚未確定的頂點中選出距離最小者並確定,對於與該頂點以邊相連的未確定頂點,若「已確定頂點的距離 + 邊的權重」小於目前的距離,就加以更新。重複此步驟,直到所有頂點都確定為止。在「6 個頂點的道路網」範例中,A→C→E→D→F 是長度 20 的最短路徑。
為什麼能正確求出
若邊的權重都在 0 以上,那麼對未確定頂點中距離最小的頂點而言,經由其他未確定頂點不可能以更短的距離到達。因為經由其他頂點時,會在至少同樣大的距離上再加上 0 以上的權重。因此在選出的當下,就能確定該頂點的距離是最短的。相反地,有負權重的邊時這個道理就不成立,因此有負權重的圖要使用 Bellman-Ford 演算法等方法。在「繞遠路反而較近的例子」中,可以確認沿著 3 條邊的路徑(3)比直接相連的 S 與 T 之間的邊(5)更短。
計算複雜度與應用場合
設頂點數為 V、邊數為 E,每次從未確定頂點中找出最小者的單純方法為 O(V²),使用堆積(優先佇列)則為 O((V + E) log V)。它被用於汽車導航與地圖 App 的路徑搜尋、網路路由協定 OSPF(各路由器由鏈路成本以戴克斯特拉演算法建立路由表),以及遊戲角色的移動路徑等。對於地圖這類大型的圖,也會使用估計目的地方向以縮小搜尋範圍的 A* 搜尋等改良版本。
考試中的步驟表
考試中常見的題型有:填寫步驟表、某個頂點第幾個被確定,以及最短距離是多少。製作表格時,要把每一步的「確定的頂點」與「更新的距離」分開寫,並注意已確定的頂點之後不再改變。最短路徑是從目的地沿著「前一個頂點」往回追溯而得。本工具表格中括號內的就是前一個頂點。
練習相關題目
- AS→A→C→T,長度8
- BS→B→A→C→T,長度7
- CS→B→C→T,長度9
查看答案與解析
正確答案:B. S→B→A→C→T,長度7
戴克斯特拉演算法反覆確定距離尚未確定的頂點中最近的一個,並更新其相鄰頂點的距離。從 S(0)開始,B 以1確定,經由 B 到 A 為 1 + 2 = 3,比直接的4短。確定 A(3)後,C 為 3 + 1 = 4、T 為 3 + 6 = 9;確定 C(4)後,T 更新為 4 + 3 = 7。因此最短路徑為 S→B→A→C→T,長度為7。S→A→C→T(8)因直接走 S−A 而較長,S→B→C→T(9)則因 B−C 的5較大而較長。
- A圖中沒有環路(回到同一頂點的路徑)
- B邊沒有方向
- C所有邊的權重都在0以上
查看答案與解析
正確答案:C. 所有邊的權重都在0以上
戴克斯特拉演算法會確定未確定頂點中距離最小者。這是基於「經由其他頂點時距離只會增加、不會減少」的前提。若有負權重的邊,之後可能經由其他路徑使距離變短;例如在 S→A 為2、S→B 為3、B→A 為−2 的有向圖中,A 以2確定之後,才找到 S→B→A 的1。有負權重時,要使用貝爾曼-福特演算法等方法。即使有環路或邊有方向,只要權重都在0以上,就能使用戴克斯特拉演算法。
- A廣度優先搜尋與佇列
- B深度優先搜尋與堆疊
- C廣度優先搜尋與堆疊
查看答案與解析
正確答案:A. 廣度優先搜尋與佇列
廣度優先搜尋依由近到遠的順序拜訪:先是從起點經1條邊可到達的頂點,再來是經2條邊可到達的頂點……。把找到的頂點放入佇列尾端、從前端取出檢查,就能維持這個「由近到遠」的順序,因此第一次到達時的邊數就是最少的邊數。深度優先搜尋(使用遞迴或堆疊)會沿著一條路盡量往前走,可能先經由繞遠的路徑到達,不保證最短。若以堆疊取代佇列,走訪方式就會接近深度優先搜尋。
- A由管理者在各路由器上手動設定路由,發生故障時,在修改設定之前會持續使用相同的路由
- B路由器之間以路由協定交換路由資訊,當故障導致路由無法使用時,會自動切換到其他路徑
- C每個封包隨機選擇路徑,把負載平均分散到多條路徑上
查看答案與解析
正確答案:B. 路由器之間以路由協定交換路由資訊,當故障導致路由無法使用時,會自動切換到其他路徑
靜態路由是由管理者手動設定路由的方法。設定簡單、行為容易預測,適合小型網路或只有一個出口之據點的預設路由,但發生故障時不會自動切換。動態路由則由路由器以OSPF、BGP等路由協定交換資訊,自動建立路由表,鏈路斷線時會重新計算其他路徑。在網際網路上,組織網路(自治系統)之間的路由以BGP交換。實際的網路一般會將兩者組合使用。
常見問題
有權重為負的邊時該怎麼辦?
無法使用戴克斯特拉演算法,要改用 Bellman-Ford 演算法。Bellman-Ford 演算法對所有的邊重複更新距離(頂點數 − 1)次,計算複雜度為 O(VE),較大,但能處理負權重,也能找出負權重的環路(每繞一圈距離就減少的迴圈)。
與廣度優先搜尋有什麼不同?
若所有邊的權重都相同,以廣度優先搜尋(BFS)就能求出邊數最少的路徑。戴克斯特拉演算法可以看成是為了處理不同權重,以依距離由小到大取出的優先佇列取代佇列的廣度優先搜尋擴充版。
要求出所有頂點對之間的最短距離該怎麼做?
可以改變起點,對每個頂點重複執行戴克斯特拉演算法,或使用 Floyd-Warshall 演算法。Floyd-Warshall 演算法以三重迴圈進行,計算複雜度為 O(V³),但步驟簡單,也能處理負權重的邊(只要沒有負環路)。
與 OSPF 有什麼關係?
OSPF 是路由器之間交換鏈路狀態(連接與成本),讓各路由器持有整個網路的地圖,並以戴克斯特拉演算法計算從自己出發之最短路徑的路由協定。在「網路路由」範例中,可以確認成本總和最小的路徑被選中的情形。