07-狄克斯特拉算法
數(shù)據(jù)結(jié)構(gòu)和算法
基于《算法圖解》—Aditya Bhargava 和《數(shù)據(jù)結(jié)構(gòu)》—嚴(yán)蔚敏
第7章 狄克斯特拉算法
上一章的廣度優(yōu)先搜索,找出的是段數(shù)最少的路徑;
本章狄克斯特拉算法,找出的是最快的路徑。
7.1 使用狄克斯特拉算法
步驟:
第一步:找出最便宜的節(jié)點
從起點出發(fā),前往節(jié)點A需要6分鐘,而前往節(jié)點B需要2分鐘。置于前往其他節(jié)點,先假設(shè)為不窮大。
第二步:計算經(jīng)節(jié)點B前往其各個鄰居所需的時間。
經(jīng)節(jié)點B可以找到前往節(jié)點A更短的路徑,只需要5分鐘。
對于節(jié)點B的鄰居,如果找到前往它的更短路徑,就更新其開銷:
- 前往節(jié)點A的更短路徑(從6分鐘縮短到5分鐘)。
- 前往終點的更短路徑(從無窮大縮短到7分鐘)。
第三步:重復(fù)
重復(fù)第一步:找出可能在最短時間內(nèi)前往的節(jié)點。 已經(jīng)對節(jié)點B執(zhí)行了第二步,除節(jié)點B外,可在最短時間內(nèi)前往的節(jié)點是節(jié)點A。 重復(fù)第二步:更新節(jié)點A的所有鄰居節(jié)點開銷。可以發(fā)現(xiàn)前往終點的時間為6分鐘。
7.1.1
使用廣度優(yōu)先搜索來查找兩點之間的最短路徑,指的是段數(shù)最少;
而在狄克斯特拉算法中,每段都分配了一個數(shù)字或權(quán)重,因此找出的是總權(quán)重最小的路徑。
狄克斯特拉算法的4個步驟:
- (1)找出最便宜的節(jié)點,即可在最短時間內(nèi)前往的節(jié)點。
- (2)對于該節(jié)點的鄰居,檢查是否有前往它們的更短路徑,如果有,就更新其開銷。
- (3)重復(fù)這個過程,直到對圖中的每個節(jié)點都這樣做了。
- (4)計算最終路徑。
7.2 術(shù)語
- 狄克斯特拉算法用于每條邊都有關(guān)聯(lián)數(shù)字的圖,這些數(shù)字稱為權(quán)重(weight)。
- 帶權(quán)重的圖為加權(quán)圖(weighted graph),不帶權(quán)重的圖為非加權(quán)圖(unweight graph)。
- 環(huán):從一個節(jié)點出發(fā),走一圈后又回到這個節(jié)點。繞環(huán)的路徑不可能是最短路徑。
- 無向圖意味著兩個節(jié)點彼此指向?qū)Ψ?#xff0c;其實就是環(huán)。在無向圖中,每條邊都是一個環(huán)。
- 狄克斯特拉算法只適用于有向無環(huán)圖(directed acyclic graph,DAG)。
7.3 換鋼琴例子
Rama想用自己的樂譜來換架鋼琴,那么需要確定哪種路徑將樂譜換成鋼琴時需要支付的額外費用最少。
使用狄克斯特拉算法可得到:
7.4 負(fù)權(quán)邊
如果有負(fù)權(quán)邊,就不能使用狄克斯特拉算法。
因為狄克斯特拉算法是這樣假設(shè)的:對于處理過的海報節(jié)點,沒有前往該節(jié)點的更短路徑。這種假設(shè)僅在沒有負(fù)權(quán)邊時才成立。
在包含負(fù)權(quán)邊的圖中,要找出最短路徑,可使用貝爾曼-福德算法。
7.5 實現(xiàn)
以下圖為例。
要編寫解決這個問題的代碼,需要三個散列表。
算法實現(xiàn)思路
準(zhǔn)備工作做好了,接下來實現(xiàn)算法。
圖4.2
7.6 小結(jié)
- 廣度優(yōu)先搜索用于在非加權(quán)圖中查找最短路徑。
- 狄克斯特拉算法用于在加權(quán)圖中查找最短路徑。
- 僅當(dāng)權(quán)重為正時狄克斯特拉算法才管用。
- 如果圖中包含負(fù)權(quán)邊,請使用貝爾曼-福德算法。
——持續(xù)修改完善中…
總結(jié)
以上是生活随笔為你收集整理的07-狄克斯特拉算法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 06-广度优先搜索:图、队列
- 下一篇: 08-贪婪算法