最短路径dijkstra算法实践:理解再实现
之前在做SDN网络控制器时,写过一个dijkstra的最短路径算法,现在回顾重温一下。
以下面的图为测试样本:
dijkstar算法的大致思想是(假设起点为A):每新到达一个点V,探测所有与该点直接相邻的点(V’)及之间的距离d(V,V’),如果V`是第一次探测到,那么记录其距离d(A,V’) = d(A,V) + d(V,V’),如果已有记录但d(A,V) + d(V,V’)小于之前的记录,则更新记录;直到所有点都被遍历。
依旧,为了方便,使用python语言,图用边的集合来表示:
|
|
初始状态
从A开始探测,则已知距离d(A,A) = 0 。
对单个点的处理
|
|
输出
|
|
一轮探测完以后,记录中新增了B C两点及它们与起点A的距离 ,那么接下来就要对B,C依次进行同样的处理了,随后对与B,C相连的点的处理……直到所有点处理完。
完成算法(使用队列)
对旧有代码进行改造:
- 将新探测到的点加入队列(待处理对象)
- 更新记录时与旧有记录作比较
增加以上功能后的代码如下:
|
|
输出为:
|
|
记录路径
以上只是输出了最短距离,但并没有记录路径,再稍微改造一下,并改以B为起点,并增加一些打印信息,方便了解算法运行过程:
|
|
输出为:
|
|
总结
dijkstar算法的正确性是如何保证的呢?因为算法在任一时刻,都保证了:
- 记录中的项是已探明路径中的最短路径。起始状态,结论显然成立:到自身距离为0。
- 探测了与所有当前点相邻的点(发现所有新路径)。对于新探测到的点,第一条路径也是唯一路径,自然是已知最短的;对于已有记录的点,则用更短路径(如果有)来更新;从而再次保证了1的成立。
当所有点都处理完,所有路径探明,记录自然就成为了到达所有点的最短路径。所以dijkstra算法其实是一个遍历所有路径,保留最小值的算法,只是选用了一个比较巧妙的遍历方式。