迪杰斯塔拉(Dijkstra)算法求最短路径
序
本文作者在学习Dijkstra算法时,发现参考书与CSDN其他博客上语言类似火星文或天书,最后,作者靠着他惊人的数学天赋总算弄懂了其原理。作者对此现象深感不平,因此,我写了一个公益性的博文,以让被火星文搞得不知所措的程序员或未来的程序员们深深的理解Dijkstra算法的奥秘。
关于Dijkstra
艾兹格·W·迪科斯彻 (Edsger Wybe Dijkstra,1930年5月11日~2002年8月6日),生于荷兰Rotterdam, 计算机科学家,毕业就职于荷兰莱顿大学,早年钻研物理及数学,而后转为计算学。曾在1972年获得过素有计算机科学界的诺贝尔奖之称的图灵奖,之后,他还获得过1974年AFIPS Harry Goode Memorial Award、1989年ACM SIGCSE计算机科学教育教学杰出贡献奖、以及2002年ACM PODC最具影响力论文奖。
——选自《百度百科:艾兹格·迪科斯彻》
Dijkstra1:
Dijkstra算法讲解
Dijkstra算法的弊端
首先,必须要清楚的是,Dijkstra算法是一种贪心算法,因此,它无法处理有负权边的图。这是因为当杜仲存在负权边时,一个未访问过的定点则有可能经由某个负权路径回流到已经访问的节点上,进而Dijkstra算法会陷入无限循环中,因此,一般的Dijkstra算法无法应用于负权图。
第一步:进行初始化
首先,我们先简单的画一个用于测试的图2:
那么,让我们先用邻接矩阵来表示它:
am = [None,
[None, inf, 3, 1, inf, inf, inf],
[None, inf, inf, inf, 3, inf, inf],
[None, inf, 1, inf, inf, 2, inf],
[None, inf, inf, inf, inf, inf, 4],
[None, inf, inf, inf, 1, inf, inf],
[None, inf, inf, inf, inf, 5, inf]
]
之所以我们把与它无关联的节点标记为“inf”是因为“0”应该表示与它距离为0的节点(也就是它自己)
Dijkstra算法中,我们需要一个用于记录从起始点到每一个节点的最短路径的长度的列表:
inf = float("inf") # 表示无穷大
dis = [inf