日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

狄克斯特拉(Dijkstra)算法原理详细解释与实现(python)

發布時間:2025/3/15 python 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 狄克斯特拉(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代碼如下:

# -*- coding:utf-8 -*- # @Author:sunaihua ''' 使用Dijkstra算法得到帶權圖的最短路徑 '''#graph 結構 graph={} graph["start"] = {} graph["start"]["a"] = 6 graph["start"]["b"] = 2 graph["a"] = {} graph["a"]["fin"] = 1 graph["b"] = {} graph["b"]["a"] = 3 graph["b"]["fin"] = 5 graph["fin"] = {}# 成本數據 infinity = float("inf") costs = {} costs["a"] = 6 costs["b"] = 2 costs["fin"] = infinity # parent數據 parents = {} parents["a"] = "start" parents["b"] = "start" parents["fin"] = None # 已經處理過的節點 processed = []def find_lowest_cost_node(costs):lowest_cost = float("inf")lowest_cost_node = Nonefor node in costs:cost = costs[node]if cost < lowest_cost and node not in processed:lowest_cost = costlowest_cost_node = nodereturn lowest_cost_nodedef dijkstra():node = find_lowest_cost_node(costs)while node is not None:cost = costs[node]neighbors = graph[node]for n in neighbors.keys():new_cost = cost + neighbors[n]if costs[n] > new_cost:costs[n] = new_costparents[n] = nodeprocessed.append(node)node = find_lowest_cost_node(costs)# 更具parents中的fin,向前反推,就可以得到最終的路徑print parentsif __name__ == '__main__':dijkstra()

總結

  • 廣度優先搜索用于在非加權圖中查找最短路徑。
  • 狄克斯特拉算法用于在加權圖中查找最短路徑。
  • 僅當權重為正時狄克斯特拉算法才管用。
  • 如果圖中包含負權邊,請使用貝爾曼-福德算法。
  • 關于最短路徑求解:

    最短路徑的常用解法有迪杰克斯特拉算法Dijkstra Algorithm, 弗洛伊德算法Floyd-Warshall Algorithm, 和貝爾曼福特算法Bellman-Ford Algorithm,其中,Floyd算法是多源最短路徑,即求任意點到任意點到最短路徑,而Dijkstra算法和Bellman-Ford算法是單源最短路徑,即單個點到任意點到最短路徑。

    ?

    ?

    總結

    以上是生活随笔為你收集整理的狄克斯特拉(Dijkstra)算法原理详细解释与实现(python)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。