Chapter 4 -- Greedy algorithms ( 3 )
Shortest Paths ( DijKstra’s Algorithm )
Scenario
$G=(V,E)\ is\ a\ directed\ graph\ and\ I(e)=lenth\ of\ edge\ e\in E,\ where\ I(e)\geq0\ can\ be\ distance,time\ or\ cost.$
$Find\ the\ shortest\ path\ P(v)\ from\ s\ to\ each\ other\ v\in V-{s},\ where\ I(P)=lenth\ of\ P=\sum_{e\in P} I(e)$
給定一個有向圖以及每個 edge 的 “長度”( 可以是距離、花費時間、花費成本…),試圖找出從 s 出發距離最短的路徑。
這邊比較特殊的是,這邊不預設終點。因這個演算法不單單可以找出給定起終點的最短路徑問題,也可以更廣泛的解決給定起點不限終點的最短路徑問題。
1 | DijKstra(G,I) |
Correctness
在證明正確性之前,我們先了解一下在演算法證明中的一些小技巧。之前說過,Greedy Algorithm 證明的兩個方向 : The Greedy Algorithm stays ahead 與 The exchange argument,在這個部份我們使用的是前者。
此外,在有 Loop 迴圈的演算法中,有時候我們會先試圖證明 Loop invariant property,在嘗試推出結果。所謂的 Loop invariant property 指的是在每一個迴圈中保持不變的性質。
Loop invariant : 在演算法執行過程中,對所有 $u\in\ S$,且 $d(u)$ 是 $s-u$ 的最短路徑 $P(u)$ 的長度。
S 的迴圈過程是一次又一次的迭代添加元素,所以我們可以用歸納法來進行證明。
Step 1. : 當 $|S|=1$,顯然成立。
Step 2. : 假設 $|S|=k\geq1$ 亦成立。
當 $|S|=k+1$ :
假設在這個迴圈中我們添加的是 $v$,且令 $(u,v)$ 為 $s-v$ 的路徑 $P(v)$ 中的最後的 edge。

對其他的 $s-v$ 路徑 $P$ 來說,在 $s,v$ 之間一定有一個路徑是從 $S$ 內的 node $x$ 指到 $S$ 外的 node $y$。
從演算法可以知道 $d(u) + I(u,v) \leq d(x) + I(x,y)+I(y,u)$
又,$d(u)$ 是 $s-u$ 的最短路徑長度。
所以,對所有的 $s-v$ 路徑來說,$s-u-v$ 這樣的路徑一定是最短路徑。
$\Longrightarrow d(v)=d(u) + I(u,v)\leq I(P)$
從上面的證明可以知道,DijKstra’s Algorithm 必須要在所有 edge 權重非負的條件下才能成立。
Implementation
在 DijKstra’s Algorithm 中,implementation 最困難的部分就是 while loop 迴圈中的第一二行,必須配合適當的資料結構才能夠真正有效率的運行 DijKstra’s Algorithm。
Min Prior Queue
Prior Queue ( 優先佇列 ) 在進行需要提取最大或最小元素的演算法中十分有用,除了 DijKstra’s Algorithm 外,還有許多演算法會建議使用 Prior Queue 來配合。
以下使用 Cormen 的 “Introduction to Algorithm” 一書中的圖例來更了解整個 DijKstra’s Algorithm 的 implementation :
