生活随笔
收集整理的這篇文章主要介紹了
最短路径Dijkstra讲解,工具包使用 python
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Dijkstra講解
原理
Dijkstra算法采用的是一種貪心的策略,聲明一個數組dis來保存源點到各個頂點的最短距離和一個保存已經找到了最短路徑的頂點的集合:T,初始時,原點 s 的路徑權重被賦為 0 (dis[s] = 0)。若對于頂點 s 存在能直接到達的邊(s,m),則把dis[m]設為w(s, m),同時把所有其他(s不能直接到達的)頂點的路徑長度設為無窮大。初始時,集合T只有頂點s
然后,從dis數組選擇最小值,則該值就是源點s到該值對應的頂點的最短路徑,并且把該點加入到T中,此時完成一個頂點, 然后,我們需要看看新加入的頂點是否可以到達其他頂點并且看看通過該頂點到達其他點的路徑長度是否比源點直接到達短,如果是,那么就替換這些頂點在dis中的值。 然后,又從dis中找出最小值,重復上述動作,直到T中包含了圖的所有頂點。
利用動態規劃來求解。
算法偽代碼
清除所有點的標號;設d[0]=0,其他d[i]=INF;//INF是一個很大的值,用來替代正無窮循環n次 { 在所有未標號結點中,選出d值最小的結點x;給結點x標記;對于從x出發的所有邊(x,y),更新d[y] = min{d[y], d[x]+w(x,y)}
根據圖來講解。假設我們要求圖中1到5 的最短路徑。
1.首先我們得到一個鄰接矩陣或者其他存儲我們的邊和點關系。
如
row
=np
.array
([1,1,1,2,2,3,3,6,5])
col
=np
.array
([2,3,6,3,4,6,4,5,4])
value
=np
.array
([7,9,14,10,15,2,11,9,6])
row和col 分別表示一條邊的兩個頂點。value表示長度。
假設我們要計算頂點1到頂點5放入最短路徑。
首先我們得有一個數組保存我們訪問過的點。
和一個矩陣保存著點到每個點的距離。矩陣大小為n*n,與源點不相鄰的邊初始值為inf 無窮大。n表示頂點個數。命名為距離矩陣
(1)從源點1出發,把源點1保存到已訪問的點數組中。發現源點1可以到達的點有頂點2,3,6修改距離矩陣中源點1到頂點2,3,6的距離。
(2)發現源點1到頂點2 的距離最小,我們走到2。把頂點2保存到已訪問的點中。
(3)到達頂點2,發現頂點2可以到達的未訪問過的點有頂點3和頂點4(頂點1為訪問過已保存到數組中),修改距離矩陣中頂點2到頂點3和頂點4的距離。。如果存在(頂點1到頂點2的距離加上頂點2到頂點3的距離)小于(頂點1到頂點3的距離),則修改距離矩陣源點1到頂點3的距離。同時修改頂點2到頂點4的距離。
(4)到達頂點3,發現頂點3可以到達的點有源點1,頂點6,頂點4。修改頂點3到頂點6和頂點4的距離為2,11。并且發現(源點1到頂點3的距離加頂點3到頂點6的距離) 小于( 源點1到頂點3的距離)。則修改距離矩陣中源點1到頂點3的距離為9+2=11。
(5)頂點3出發,選擇最近的點,到達頂點6。頂點5可以到達的點為源點1和頂點6,修改頂點5到頂點6的距離。同時修改頂點1到頂點5的距離為9+2+9
所有頂點1到頂點5最短路徑 頂點1-頂點3-頂點6-頂點5.
公式
源點到頂點j的距離=min(源點到頂點j的距離(開先定義的距離數據庫中距離),源點到頂點j相鄰點i的距離+頂點i與頂點j的距離)
networkx 使用求解
無向圖
nx.Graph() 無向圖
import networkx
as nx
import pylab
import numpy
as np
import matplotlib
; matplotlib
.use
('TkAgg')
from pylab
import *
mpl
.rcParams
['font.sans-serif'] = ['SimHei']
mpl
.rcParams
['axes.unicode_minus'] = False
row
=np
.array
([0,0,0,1,1,2,2,5,4])
col
=np
.array
([1,2,5,2,3,5,3,4,3])
value
=np
.array
([7,9,14,10,15,2,11,9,6])print('生成一個空的有向圖')
G
=nx
.Graph
()
print('為這個網絡添加節點...')
for i
in range(0,np
.size
(col
)+1):G
.add_node
(i
)
print('在網絡中添加帶權中的邊...')
for i
in range(np
.size
(row
)):G
.add_weighted_edges_from
([(row
[i
],col
[i
],value
[i
])])print('給網路設置布局...')
pos
=nx
.shell_layout
(G
)
print('畫出網絡圖像:')
nx
.draw
(G
,pos
,with_labels
=True, node_color
='white', edge_color
='red', node_size
=400, alpha
=0.5 )
pylab
.title
('路徑圖',fontsize
=15)
pylab
.show
()print('dijkstra方法尋找最短路徑:')
path
=nx
.dijkstra_path
(G
,source
=0, target
=4)
print('節點0到4的路徑:真實1到5', path
)
print('dijkstra方法尋找最短距離:')
distance
=nx
.dijkstra_path_length
(G
, source
=0, target
=4)
print('節點0到4的距離為:', distance
)
row=np.array([0,0,0,1,1,2,2,5,4])
col=np.array([1,2,5,2,3,5,3,4,3])
value=np.array([7,9,14,10,15,2,11,9,6])
row 和col 對應邊的兩個頂點 :0對應原始圖中的1,1對應原始圖中的2,value為長度。
路徑圖
結果:
路徑對應原始圖中為1,3,6,5。
有向圖
G=nx.DiGraph()# 為有向圖
import networkx
as nx
import pylab
import numpy
as np
import matplotlib
; matplotlib
.use
('TkAgg')
from pylab
import *
mpl
.rcParams
['font.sans-serif'] = ['SimHei']
mpl
.rcParams
['axes.unicode_minus'] = False
row
=np
.array
([0,0,0,1,1,2,2,5,4])
col
=np
.array
([1,2,5,2,3,5,3,4,3])
value
=np
.array
([7,9,14,10,15,2,11,9,6])print('生成一個空的有向圖')
G
=nx
.DiGraph
()
print('為這個網絡添加節點...')
for i
in range(0,np
.size
(col
)+1):G
.add_node
(i
)
print('在網絡中添加帶權中的邊...')
for i
in range(np
.size
(row
)):G
.add_weighted_edges_from
([(row
[i
],col
[i
],value
[i
])])print('給網路設置布局...')
pos
=nx
.shell_layout
(G
)
print('畫出網絡圖像:')
nx
.draw
(G
,pos
,with_labels
=True, node_color
='white', edge_color
='red', node_size
=400, alpha
=0.5 )
pylab
.title
('路徑圖',fontsize
=15)
pylab
.show
()print('dijkstra方法尋找最短路徑:')path
=nx
.dijkstra_path
(G
,source
=4, target
=5)
print('節點4到5的路徑', path
)
print('dijkstra方法尋找最短距離:')
distance
=nx
.dijkstra_path_length
(G
, source
=4, target
=5)
print('節點4到5的距離為:', distance
)
求4到5的距離:
運行顯示報錯。沒有路徑可達
總結
以上是生活随笔為你收集整理的最短路径Dijkstra讲解,工具包使用 python的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。