遍历所有点的最短路径python_图遍历算法之最短路径Dijkstra算法
一、最短路徑問題(shortest path problem)
最短路徑問題是圖論研究中一個(gè)經(jīng)典算法問題,旨在尋找圖中兩節(jié)點(diǎn)或單個(gè)節(jié)點(diǎn)到其他節(jié)點(diǎn)之間的最短路徑。根據(jù)問題的不同,算法的具體形式包括:
確定起點(diǎn)的最短路徑問題,即給定起始節(jié)點(diǎn),求該節(jié)點(diǎn)到其他剩余節(jié)點(diǎn)的最短路徑,適合使用Dijkstra算法;
確定終點(diǎn)的最短路徑問題,即給定終點(diǎn),求其他節(jié)點(diǎn)到該終點(diǎn)的最短路徑。在無向圖中,該問題與確定起點(diǎn)的問題等價(jià);在有向圖中,問題等價(jià)于把所有路徑方向反轉(zhuǎn)的確定起點(diǎn)的問題;
確定起點(diǎn)終點(diǎn)的最短路徑問題,即給定起點(diǎn)和終點(diǎn),求兩節(jié)點(diǎn)之間的最短路徑;
全局最短路徑問題,即求圖中所有節(jié)點(diǎn)之間的最短路徑,適合使用Floyd-Warshall算法。
常用的最短路徑算法包括:Dijkstra算法,A
算法,Bellman-Ford算法,SPFA算法(Bellman-Ford算法的改進(jìn)版本),Floyd-Warshall算法,Johnson算法以及Bi-direction BFS算法。本文將重點(diǎn)介紹Dijkstra算法的原理以及實(shí)現(xiàn)。
二、Dijkstra算法介紹
1. 算法概覽
Dijkstra算法,翻譯作戴克斯特拉算法或迪杰斯特拉算法,于1956年由荷蘭計(jì)算機(jī)科學(xué)家艾茲赫爾.戴克斯特拉提出,用于解決賦權(quán)有向圖的單源最短路徑問題。所謂單源最短路徑問題是指確定起點(diǎn),尋找該節(jié)點(diǎn)到圖中任意節(jié)點(diǎn)的最短路徑,算法可用于尋找兩個(gè)城市中的最短路徑或是解決著名的旅行商問題。
問題描述:在無向圖
中,
為圖節(jié)點(diǎn)的集合,
為節(jié)點(diǎn)之間連線邊的集合。假設(shè)每條邊
的權(quán)重為
,找到由頂點(diǎn)
到其余各個(gè)節(jié)點(diǎn)的最短路徑(單源最短路徑)。
2. 算法描述
為帶權(quán)無向圖,圖中頂點(diǎn)
分為兩組,第一組為已求出最短路徑的頂點(diǎn)集合(用
表示)。初始時(shí)
只有源點(diǎn),當(dāng)求得一條最短路徑時(shí),便將新增頂點(diǎn)添加進(jìn)
,直到所有頂點(diǎn)加入
中,算法結(jié)束。第二組為未確定最短路徑頂點(diǎn)集合(用
表示),隨著
中頂點(diǎn)增加,
中頂點(diǎn)逐漸減少。
初始化:
只包含起點(diǎn)
,
包含
外的其他頂點(diǎn)。
中的距離為起點(diǎn)
到頂點(diǎn)的距離。若
與
相鄰,則
中頂點(diǎn)
距離為
的邊緣權(quán)重;若
與
不相鄰,則
的距離為
;
更新
和
:從
中選出距離值最小的頂點(diǎn)
,并將頂點(diǎn)
添加至
;同時(shí),從
中移除
;
更新
中頂點(diǎn)到起點(diǎn)
的距離:由于
中添加了
,利用
進(jìn)一步更新
到其他頂點(diǎn)的距離,存在
的可能性;
反復(fù)迭代:重復(fù)第二步和第三步,直到遍歷完所有節(jié)點(diǎn)。
3. 算法示例
以下圖為例,對(duì)Dijkstra算法的工作流程進(jìn)行演示(以頂點(diǎn)
為起點(diǎn)):
圖1. 有權(quán)無向圖G
注:
01)
是已計(jì)算出最短路徑的頂點(diǎn)集合;
02)
是未計(jì)算出最短路徑的頂點(diǎn)集合;
03)
表示頂點(diǎn)
到頂點(diǎn)
的最短距離為3
第1步:選取頂點(diǎn)
添加進(jìn)
圖2. 第1步
第2步:選取頂點(diǎn)
添加進(jìn)
,更新
中頂點(diǎn)最短距離
圖3. 第2步
第3步:選取頂點(diǎn)
添加進(jìn)
,更新
中頂點(diǎn)最短距離
圖4. 第3步
第4步:選取頂點(diǎn)
添加進(jìn)
,更新
中頂點(diǎn)最短距離
圖5. 第4步
第5步:選取頂點(diǎn)
添加進(jìn)
,更新
中頂點(diǎn)最短距離
圖6. 第5步
第6步:選取頂點(diǎn)
添加進(jìn)
,更新
中頂點(diǎn)最短距離
圖7. 第6步
第7步:選取頂點(diǎn)
添加進(jìn)
,更新
中頂點(diǎn)最短距離
圖8. 第7步
三、Dijkstra算法的R及Python軟件實(shí)現(xiàn)
1. R實(shí)現(xiàn)Dijkstra算法:igraph包中shortest.paths函數(shù)
示例:node編號(hào)1-7分別代表A,B,C,D,E,F,G
require(igraph)
graph_matrix
"node x1 x2 x3 x4 x5 x6 x7
1 0 12 NA NA NA 16 14
2 12 0 10 NA NA 7 NA
3 NA 10 0 3 5 6 NA
4 NA NA 3 0 4 NA NA
5 NA NA 5 4 0 2 8
6 16 7 6 NA 2 0 9
7 14 NA NA NA 8 9 0
", header=T))
nms
mat
colnames(mat)
mat[is.na(mat)]
# create graph from adjacency matrix
g
# Get all path distances
(s.paths
(s.paths
(s.paths
1 2 3 4 5 6 7
1 0 12 22 22 18 16 14
2 12 0 10 13 9 7 16
3 22 10 0 3 5 6 13
4 22 13 3 0 4 6 12
5 18 9 5 4 0 2 8
6 16 7 6 6 2 0 9
7 14 16 13 12 8 9 0
(s.paths
1 2 3 4 5 6 7
4 22 13 3 0 4 6 12
2. Python語言實(shí)現(xiàn)Dijkstra算法:networkx 模塊
示例:
from dijkstar import Graph, find_path
graph=Graph()
graph.add_edge(1,2,{'cost':12})
graph.add_edge(1,6,{'cost':16})
graph.add_edge(1,7,{'cost':14})
graph.add_edge(2,3,{'cost':10})
graph.add_edge(2,6,{'cost':7})
graph.add_edge(2,1,{'cost':12})
graph.add_edge(3,2,{'cost':10})
graph.add_edge(3,4,{'cost':3})
graph.add_edge(3,5,{'cost':5})
graph.add_edge(3,6,{'cost':6})
graph.add_edge(4,3,{'cost':3})
graph.add_edge(4,5,{'cost':4})
graph.add_edge(3,5,{'cost':5})
graph.add_edge(3,6,{'cost':6})
graph.add_edge(4,3,{'cost':3})
graph.add_edge(4,5,{'cost':4})
graph.add_edge(5,3,{'cost':5})
graph.add_edge(5,4,{'cost':4})
graph.add_edge(5,6,{'cost':2})
graph.add_edge(5,7,{'cost':8})
graph.add_edge(6,1,{'cost':16})
graph.add_edge(6,2,{'cost':7})
graph.add_edge(6,3,{'cost':6})
graph.add_edge(6,5,{'cost':2})
graph.add_edge(6,7,{'cost':9})
graph.add_edge(7,1,{'cost':14})
graph.add_edge(7,5,{'cost':8})
graph.add_edge(7,6,{'cost':9})
cost_func = lambda u, v, e, prev_e: e['cost']
find_path(graph, 4, 7, cost_func=cost_func)
找到D(4)到G(7)的最短路徑:
PathInfo(nodes=[4, 5, 7], edges=[{'cost': 4}, {'cost': 8}], costs=[4, 8], total_cost=12)
參考資料:
總結(jié)
以上是生活随笔為你收集整理的遍历所有点的最短路径python_图遍历算法之最短路径Dijkstra算法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 价值几千行代码的一键安装开源啦,欢迎各位
- 下一篇: websocket python爬虫_p