Dijsktra的逻辑相信大家都已经有所了解,就是利用已知节点的最短路径进行贪心遍历,主要用于单源节点最短路径问题。
对于多源点最短路径和带负权边的问题,可以参考Floyd算法。
指路==>Folyd最短路径算法的python实现
引用知乎的一个最短路径图如下
则对应python代码为(节点编号从1开始,所以代码中的索引记得减1)
from queue import PriorityQueue
def dijsktra(adjacency_graph, start):
v_num = len(adjacency_graph)
paths = [None] * v_num
cands = PriorityQueue()
cands.put((0, start, start)) # 分别为最短路径长度,最短路径到达该节点的前驱节点,当前节点(节点从1开始编号)
cnt = 0
while cnt < v_num and not cands.empty():
min_len, u, v_min = cands.get()
v_min -= 1 # 顶点编号修改为索引编号
if paths[v_min]: # 当前节点到起点的最短路径已知,跳过
continue
paths[v_min] = (u, min_len) # 记录新的最短路径
for v, w in adjacency_graph[v_min]: # 考察经过顶点v_min的最短路径
if not paths[v - 1]:
cands.put((min_len + w, v_min, v))
cnt += 1
return paths
def main():
# 邻接表,每一项分别由邻接节点(从1开始编号)和对应cost组成
adjacency_graph = [[(2, 2), (3, 5), (4, 4)],
[(3, 2), (4, 1)],
[(4, 1)],
[]]
res = dijsktra(adjacency_graph, 1)
print(res)
代码中应该没有太多其他不相关内容,大家结合dijsktra逻辑按着代码推一遍就理解啦。