本文用python实现了Dijkstra算法,算法原理见最短路径问题:Dijkstra算法原理和证明。
1import sys
2def Dijkstra(name_list, W, s):
3 '''
4 Dijkstra 算法:计算从源点到其他点的最短距离
5 W:权重矩阵,存放图中所有边的非负权值,对称矩阵
6 name_list:按照顺序存放W中点的名称,从0开始
7 s:源点(点名称)
8 return:存放源点到其他点的最短距离
9 '''
10 # 将点名称s改为点索引s
11 for i,name in enumerate(name_list):
12 if name == s:
13 s = i
14 break;
15 # 初始化
16 MAX = sys.maxsize # 权值的上限
17 dist = [MAX for x in range(len(name_list))] # s到所有点的距离,初始化为最大值
18 dist[s] = 0 # s到s的距离为0
19 min_point = s # 距离s最短的点为s
20 T = set() # 存放已经算出最短距离的点,初始化为空
21 # 开始循环
22 while (len(T) < len(name_list)): # 一直循环直至T包含了所有点
23 T.add(min_point) # 将距离最短的点加入到T中
24 for i,w in enumerate(W[min_point]): # 遍历min_point的所有直接相连的点
25 if i not in T and w > 0: # 只需要更新不属于T的、权值大于0的点
26 dist[i] = min(dist[i], dist[min_point] + W[min_point][i]) # 取最小值
27 # 选出不属于T的距离的最小值
28 min_dist = MAX
29 for i,d in enumerate(dist):
30 if i not in T and d > 0 and d < min_dist:
31 min_dist = d
32 min_point = i
33 return dict((name_list[i],d) for i,d in enumerate(dist)) # 将结果集中的点索引换为点名称,放入到词典中
34if __name__ == '__main__':
35 MAX = sys.maxsize
36 W = [[0,9,4,MAX],
37 [9,0,3,1],
38 [4,3,0,1],
39 [MAX,1,1,0]]
40 name_list = ['A','B','C','D']
41 print(Dijkstra(name_list,W,'A'))
代码的github:
https://github.com/HappyRocky/pythonAI/blob/master/algorithm-exercise/Dijkstra.py
如代码中出现逻辑错误或者可以优化,欢迎指正。