狄克斯特拉(Dijkstra)算法原理详细解释与实现(python)
目錄
寫在前面
1. 簡介
2. 原理
2.1 找出最便宜的節點
2.2 計算前往該節點的各個鄰居的開銷
2.3 重復上面的步驟
實現
總結
寫在前面
本文原理摘自《算法圖解》這本書。
其實Dijkstra算法是廣度優先搜索基礎上擴展來的。無非是廣度優先搜索按照層次關系,每一層級每一個節點都進行重復操作,直到找到合適的解法,接著進入下一層級。
Dijkstra算法是對每一層級每一個節點找到其符合條件解法,然后進行更新,接著進行下一層級。
?
1. 簡介
廣度優先算法可以找出段數最少的路徑,但是對于路徑上帶權重的圖,想要找出最快的路徑,則需要使用狄克斯特拉算法。
2. 原理
為了說明狄克斯特拉算法的原理,使用換鋼琴的的例子來做說明.
假設Rama想拿自己的樂譜換架鋼琴:
Alex說:“這是我最喜歡的樂隊Destroyer的海報,我愿意拿它換你的樂譜。
如果你再加5美元,還可拿樂譜換我這張稀有的Rick Astley黑膠唱片。”
Amy說:“哇,我聽說這張黑膠唱片里有首非常好聽的歌曲,我愿意拿我的吉他或架子鼓換這張海報或黑膠唱片。
Beethoven驚呼:“我一直想要吉他,我愿意拿我的鋼琴換Amy的吉他或架子鼓。”
商品兌換的關系如下:
現在需要確定,Rama如何才能以最少的錢換到他想要的鋼琴。
狄克斯特拉算法解決問題的思路主要包括以下四步:?
找出最便宜的節點,即可用最便宜的價格可前往的節點。
對于該節點的鄰居,檢查是否有前往它們的更短路徑,如果有,就更新其開銷。
重復這個過程,直到對圖中的每個節點都這樣做了。
計算最終路徑
下面結合狄克斯特拉的算法步驟,對該問題進行推算。
2.1 找出最便宜的節點
對于樂譜而言,可以直接兌換唱片和海報,所需的費用分別為5和0.
為了觀察的算法過程中數據的變化情況,使用一個表格來計算兌換的開銷以及父節點的情況,對于目前開銷的未知的節點用無窮大來表示,經過該步驟后,數據的情況如下:
| 樂譜 | 唱片 | 5 |
| 樂譜 | 海報 | 0 |
| – | 吉他 | ∞ |
| – | 架子鼓 | ∞ |
| – | 鋼琴 | ∞ |
2.2 計算前往該節點的各個鄰居的開銷
通過步驟1的處理,得知從樂譜->海波的開銷是最小的。此時計算從海報到達各鄰居節點的開銷,如果鄰居節點的開銷變少了,則更新其開銷和父節點。最終的結果如下:
| 樂譜 | 唱片 | 5 |
| 樂譜 | 海報 | 0 |
| 海報 | 吉他 | 30 |
| 海報 | 架子鼓 | 35 |
| – | 鋼琴 | ∞ |
2.3 重復上面的步驟
接下來還沒有被遍歷的節點中,最便宜的兌換商品為唱片,此時計算從唱片到達各鄰居節點的開銷,通過計算,從唱片到達吉他只需20,從唱片到達架子鼓只需25,因此需要更新結果表中吉他和架子鼓的父節點以及成本,最終結果如下:
| 樂譜 | 唱片 | 5 |
| 樂譜 | 海報 | 0 |
| 唱片 | 吉他 | 20 |
| 唱片 | 架子鼓 | 25 |
| – | 鋼琴 | ∞ |
接下來最便宜的節點是吉他,從吉他這個路徑走,到鋼琴的價格為40.接z最后是架子鼓,從架子鼓這個路徑走,到鋼琴的價格為35. 于是最終結果如下:
| 樂譜 | 唱片 | 5 |
| 樂譜 | 海報 | 0 |
| 唱片 | 吉他 | 20 |
| 唱片 | 架子鼓 | 25 |
| 架子鼓 | 鋼琴 | 35 |
通過上述表格反推,花費最小的兌換路徑為:樂譜–>唱片–>架子鼓–>鋼琴,需要花費35.
實現
代碼的實現中,需要維護三個散列表:
graph:用來描述頂點與邊的關系,為了簡單演示,可以直接使用字典的形式表示頂點與邊。
costs:用來記錄途徑頂點的開銷
parents:用來記錄各頂點的父頂點情況
python代碼如下:
總結
關于最短路徑求解:
最短路徑的常用解法有迪杰克斯特拉算法Dijkstra Algorithm, 弗洛伊德算法Floyd-Warshall Algorithm, 和貝爾曼福特算法Bellman-Ford Algorithm,其中,Floyd算法是多源最短路徑,即求任意點到任意點到最短路徑,而Dijkstra算法和Bellman-Ford算法是單源最短路徑,即單個點到任意點到最短路徑。
?
?
總結
以上是生活随笔為你收集整理的狄克斯特拉(Dijkstra)算法原理详细解释与实现(python)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android 渠道方案,Android
- 下一篇: 大数据2019年的三大趋势你看了吗?