想写一篇关于最短路径的算法发现自己画图不够好,看到一篇博客简单清楚的解释了算法的含义,搬运过来了,后面是我补充的。
以顶点A作为出发点为例,来说明Dijkstra算法过程。
(1)设置两个集合,S集合和V集合。S集合初始只有源顶点即顶点A,V集合初始为除了源顶点以外的其他所有顶点。
设置一个数组dist用来表示顶点A到其他顶点的最短距离,初始化为-1(表示无穷大)。
(2)遍历集合V中与A直接相邻的顶点,找出当前与A距离最短的顶点。
发现:
A->C = 3
A->B = 6
于是乎,将C移除集合V将其加入到集合S中,于此同时更新dist数组
dist[C] = 3
dist[B] = 6
注意:这个时候虽然只将C从V中移除,但是更新的时候C,B都要更新。
(3)遍历集合V中与C相邻的顶点,(图中C与B,D,E相连)
发现 C->B = 2 , C->D = 3 , C->E = 4,由于目前dist中最短距离 A->C = 3 即 dist[C] = 3,那么:
A->B = 3 + 2 =5
A->D = 3 + 3 = 6
A->E = 3 + 4 = 7
而目前在dist中:
A->B = 6
A->D = -1
A->E = -1
经过比较,将顶点B加入集合S中,并将其从V集合中删除,更新dist中A->B ,A->D,A->E的记录即:
dist[B] = 5
dist[D] = 6
dist[E] = 7
(4)遍历集合V中与B相邻的顶点,发现 B->D = 5,在dist中可以查到最短距离A->B = 5, 那么:
A->D = 5 + 5 = 10
而目前在dist中:
A->D = 6
所以,将D加入到集合S中,并将其从V集合中删除,不更新dist数组相应的值,因为disk中值为6<10。更新后如下
(5)遍历集合V中与D相邻的顶点,
发现 D->E = 2 , D->F = 3, 在dist中可以查到最短距离A->D = 6,那么:
A->E = 6 + 2 = 8
A->F = 6 + 3 = 9
而在dist中:
A->E = 7
A->F = -1
所以将E从集合V中删除并加入到集合S中,并更新dist中的:
dist[E]不更新,因为原dist为7<8
dist[F] = 9
(因为A到E距离小于A到F的距离,所以从V中删除E而不删除F)
(6)由于到目前为止只剩下顶点F,所以将F也加入到集合S中,至此算法运行结束。
由此,dist数组就是表示从源点A出发到达其他各个顶点的最短路径,比如 A->F,dist[F] = 9。
'''
Dijkstra smallest pathway
find the smallest pathway from A to other vertice
Date: 2020-9-18
'''
# 生成小写字母: vertice = [chr(i) for i in range(97,103)]
import numpy as np # 生成大写字母
aaa = np.arange(65,71) # 生成大写字母
vertice = [chr(i) for i in aaa] # 生成大写字母
ver_num = len(vertice)
MAX= float('inf')
matrix = [ # 路径矩阵
#A B C D E F
[0,10,MAX,4,MAX,MAX], # A matrix[0] 第一行
[10,0,8,2,6,MAX], # B
[MAX,8,10,15,1,5], # C
[4,2,15,0,6,MAX], # D
[MAX,6,1,6,0,12], # E
[MAX,MAX,5,MAX,12,0] # F
]
opt_dst = [MAX] * len(matrix) # the optimal distance from A to others
opt_dst[0] = 0
SmaPathVer = ['A'] # smallest pathway vertice list
opt_ver = 'A'
while len(SmaPathVer) <= len(matrix)-1:
# 更新opt_dst
for i in range(ver_num):
if vertice[i] in SmaPathVer:
opt_dst[i] = opt_dst[i]
else:
para = ord(opt_ver)-65
opt_dst[i] = min(opt_dst[i], opt_dst[para]+matrix[para][i]) ###
# 更新下一个最佳路径的节点
minnum = max(opt_dst)
for i in range(ver_num):
if vertice[i] in SmaPathVer:
continue
else:
if opt_dst[i] <= minnum:
minnum = opt_dst[i]
opt_ver = chr(65+i)
SmaPathVer.append(opt_ver)
print(opt_dst)