路漫漫其修遠兮,吾將上下而求索。
——屈原
在最短路徑的求解算法中,迪傑斯特拉(Dijkstra)算法應該是非常出名的,但是對於初學者而言卻又很難理解爲什麼這個算法是對的,找到的就是最短路徑。下面博主參考了相關資料,和大家談談如何理解迪傑斯特拉算法。
一、鬆弛(relaxation)
所謂“鬆弛”是從國外的文獻資料上的單詞“relaxation”直譯而來的,亦可以翻譯成“弛豫”。那麼,到底什麼是鬆弛呢?
我們先來看下面這張圖片。
上圖中,原來認爲頂點
上述過程就是所謂的“鬆弛”,即好像將原來“緊繃”的“弦”(路
二、(最優子結構)從vi 到vj 的最短路上所經過的頂點vk 一定滿足vi 到vk 的路徑爲最短路
標題中所給出的結論是顯然的。下面我們通過反證法做一些論證。
假設已知上圖中實線所示的路徑爲
三、(貪心選擇性質)對於無負權環的圖G ,若頂點v 所對應的距離爲V−U 中頂點在距離表中的最小值,則源點到v 的最短路已經找到
上述結論中,
首先介紹距離表。所謂距離表,就是記錄當前求得的從源點
依然利用反證法論述上述結論。
假如該最小值所對應的頂點
但是,上述論述都需要一個前提,就是圖中不含負權環!
四、迪傑斯特拉算法的運行過程
下面,終於正式進入迪傑斯特拉算法的解釋。
首先,我們需要開兩個集合
同時我們還要開一個表,來記錄當前求得的從源點
初始時,集合
接着每一次循環都將距離表中最短距離所對應的頂點拉入集合
對於上一步驟的正確性,前文已經給出解釋。首先,認爲距離表中
如此的循環下去直到所有頂點都被拉入集合
可以從下面的例子來理解上述過程。
下面,從距離表中找到距離最小的頂點2,然後將2號頂點加入集合
在距離表中找到最小值30,將對應的4號頂點拉進集合
在距離表中找到最小值50,將對應的3號頂點拉進集合
再將5號頂點拉入集合
五、存在的問題
由於上述更新的過程中,如果發現頂點
那麼,我們該怎麼面對帶有負權環的圖呢?歷史上,Richard Bellman和Lester Ford等人給出了他們的解決方案,稱爲Bellman-Ford算法,它可以幫助我們判斷
參考資料:
[1] 最短路徑算法——Dijkstra(迪傑斯特拉)算法分析與實現(C/C++)
[2] 算法(第4版),塞奇威克(Robert Sedgewick)、韋恩(Kevin Wayne)著