- 迪杰斯特拉算法采用动态规划的算法,从起点开始,遍历子节点并计算两节点之间的距离,并比较,更新数据后继续遍历。
- 该算法适用于边的距离为正数的简单图。
- 下面的算法通过堆的数据结构,通过hd记录两节点之间的距离并更新最小距离。
- 参数
(1)s: 起点 (2) vetix_list: 图中的全部节点(3)graph: 图中节点的连接关系 (4)edge: 两节点间的距离 - 返回值:起始节点到所有节点最小距离的字典。
def Dijkstra(s, vertx_list, graph, edges):
hd = heapdict() # 构建堆字典,用于记录与更新两点(起始点与目的节点)间的距离
distance_map = {} # 记录起始节点到其它所有节点的最短路径
for v in vertx_list: # 将起始节点与其它节点的距离加入小堆
if v == s: # 节点自身与自身的距离设为0
hd[(s, v)] = 0
distance_map[(s, v)] = 0
else: # 节点间的距离设为无穷大
hd[(s, v)] = np.inf
distance_map[(s, v)] = np.inf
edge = hd.peekitem() # 堆顶的项目: (('A', 'A'), 0)
while edge is not None:
point_in_edge = edge[0] # ('', '') 相连的两个点
second_point = point_in_edge[1] # 第二个节点
update = False
for connect_point in graph[second_point]: # connect_point(连接点): 与第二个节点有相连的点
edge_len = edges[(second_point, connect_point)] # 两个新的连接点边长
if hd[(s, second_point)] + edge_len < distance_map[(s, connect_point)]:
# 如果新的连接点更短,更新最短距离
print("path from {0} to {1} to {2} is shorter with length {3}"
.format(s, second_point, connect_point, hd[(s, second_point)]+edge_len))
hd[(s, connect_point)] = hd[(s, second_point)] + edge_len
distance_map[(s, connect_point)] = hd[(s, second_point)] + edge_len
update = True
if not update: # 一旦堆元素有更新时不能把顶部元素弹出,因为被更新后的元素可能恰好处于堆顶。
# 如果没有更新,已经是最短距离,删去堆顶项目
# print(hd.peekitem())
hd.popitem()
if hd.__len__() == 0:
edge = None
else:
edge = hd.peekitem()
return distance_map
应用:
图为:
vertex_list_ = ['A', 'B', 'C', 'D', 'E', "F", 'G'] # 记录图中所有节点
graph_ = {"A": ['B', 'E'], 'B': ['C', 'E'], 'E': ['C'], 'C': ['D', 'F'], 'F': ['G'], 'G': ['D'],
'D': ['D']} # 记录节点与节点的连接关系
edge_ = {("A", 'B'): 2, ("A", 'E'): 8, ("B", 'E'): 3, ("B", 'C'): 5, ("E", 'C'): 4, ("C", 'F'): 3, ("C", 'D'): 7,
("G", 'D'): 1, ("F", 'G'): 2, ("D", 'D'): 0} # 记录边长度
distance = Dijkstra("A", vertex_list_, graph_, edge_)
``
运行结果:
```python
path from A to A to B is shorter with length 2
path from A to A to E is shorter with length 8
path from A to B to C is shorter with length 7
path from A to B to E is shorter with length 5
path from A to C to D is shorter with length 14
path from A to C to F is shorter with length 10
path from A to F to G is shorter with length 12
path from A to G to D is shorter with length 13
进程已结束,退出代码为 0
添加代码
for key in distance.keys():
print("The shortest distance from {0} to {1} is {2}"
.format(key[0], key[1], distance[key]))
可得到起始节点到所有节点的最短距离。
The shortest distance from A to A is 0
The shortest distance from A to B is 2
The shortest distance from A to C is 7
The shortest distance from A to D is 13
The shortest distance from A to E is 5
The shortest distance from A to F is 10
The shortest distance from A to G is 12
进程已结束,退出代码为 0