dijkstra 算法的实现和难点浅析

这是一个神奇的算法,要慢慢消化。

大学里学数据结构的时候,就已经开始接触这个算法了。不过,当时的概念是理解了,但是伪代码怎么都没看懂。

现在看来,我对这个算法的描述,也没怎么理解透彻。趁有时间,又研究了下,发现原来他的实现过程也没那么复杂。只是,里面的变量实在有点多,在没明白其中的缘由的情况下,那当然是看不懂了。有这次机会,绝对不能放过。深入研究了其中的各个变量的含义,再看实现逻辑,也是如此的顺风顺水……

算法,光理解算法还不行,还是要实现看看,不管是看别人的,还是自己写。不然,你感觉你理解了,不一定能实现。这个不讲算法的概念,还没接触过的,请自行脑补。

看图:

090901_oMRH_581482.png

代码如下:

#!/usr/bin/env python
#encoding=utf8
#dijkstra.py

I = 10000
MAXVEX = 9
ShortPathTable = [0,0,0,0,0,0,0,0,0]
Pathmatrix = [0,0,0,0,0,0,0,0,0]
G = [
[I,1,5,I,I,I,I,I,I],
[1,I,3,7,5,I,I,I,I],
[5,3,I,I,1,7,I,I,I],
[I,7,I,I,2,I,3,I,I],
[I,5,1,2,I,3,6,9,I],
[I,I,7,3,I,I,I,5,I],
[I,I,I,3,6,I,I,2,7],
[I,I,I,I,9,5,2,I,4],
[I,I,I,I,I,I,7,4,I],
]

# print roadPath

#djkstra algrithm
def dijkstra(G,v0,Pathmatrix,ShortPathTable):
     final = [0,0,0,0,0,0,0,0,0]
    
     for v in xrange(MAXVEX):
          final[v] = 0
          ShortPathTable[v] = G[v0][v]
          Pathmatrix[v] = 0
     ShortPathTable[v0] = 0;
     final[v0] = 1
    
     for v in xrange(1,9):
          minPath = I
          for w in xrange(9):
               if final[w] != 1 and ShortPathTable[w] < minPath:
                    k = w
                    minPath = ShortPathTable[w]

          final[k] = 1

          for w in xrange(9):
               # 当前最短路径的后驱和与前一个节点
               if final[w] != 1 and minPath+G[k][w] < ShortPathTable[w]:
                    ShortPathTable[w] = minPath+G[k][w]
                    Pathmatrix[w] = k

dijkstra(G,0, Pathmatrix, ShortPathTable)

print ShortPathTable
print Pathmatrix


(这个代码是我按照C的代码重构成python)。


我解释一下这里面的变量的作用:G:这个指向的是无向图的存储数组,V0是程序的入口节点,Pathmatrix:存储的最短路径的序列(也就是从V0到任何一个点的最短路径,需要通过哪些节点),ShortPathTable:到某个点的最短路径的距离,final :最短路径状态标志,如果找到了,则这个节点将被置成1,循环的时候会跳过这些点.

先介绍一下这个算法里的几个循环是干什么用的:

1、 第一个循环,初始化该节点到其余节点的路径,也就是把矩阵的第一行数据复制到ShortPathTable(这个变量很重要,每次大循环都以它为基础),Pathmatrix里的值全部置零。

2、 第二个循环,这个大循环才是算法的真正实施,每一次循环都确保能找到到某个点的最短路径。

3、第三个循环,属于第二个循环的内部循环,每次执行,从未找到最短路径的节点中,找到距离最短的那个(ShortPathTable 当中数值最小的那个)。

4、第四个循环,属于第二个循环的内部循环,更新符合条件minPath+G[k][w] < ShortPathTable[w]  的值(minPath 是第三个循环找到的数值最小的那个),并将该值更新到ShortPathTable里面,最后再更新Pathmatrix,即到达w点,对应的前驱结点。


第二个循环,才是核心的循环。每次遍历都能找到一个对应的最短路径。


下一步,我看看调试执行的过程。其实,最难理解的地方,就是执行过程如何与代码的执行结合到一起的。


开始执行,第一个循环结束后,看Pathmatrix,ShortPathTab,final的值:

ShortPathTable[v0] = 0;
final[v0] = 1

这两个初始化的执行,v0到自身的距离,已经找到,所以final[1] 的值被置成1,ShortPathTable[1]的值被置成0(说明v0到自身的距离为0). 初始化流程结束。

094709_V8iJ_581482.png

2,看一下,核心循环的执行过程:

第一个子循环结束后的结果:

094720_X1G1_581482.png

遍历ShortPathTable 排除已经找到最短距离的节点,查找在未找到最短距离的节点中,距离最短的那个。本次执行后找到的最短距离,是到节点编号为1的,距离为1。那节点1,将会从所有节点中排除,即执行final[1]=1。


再看第二个子循环:

094746_YYl1_581482.png

这一步才是真正体现智慧的地方。以k为基准,扫描与k直接相连的节点的距离在加上k到前驱结点的距离,与v0节点到与k直连节点的距离进行比较,也就是当这个条件minPath+G[k][w] < ShortPathTable[w]成立时,将这个距离更新到ShortPathTable。简单点说,让v0节点到各点的距离,在通过了vk节点后,做一次更新,比如,v0不能直接到v4,但是在通过了v1节点后就到v4了。不过这个时候,还做了另外一件事, v0与v2是直连的,距离为5,但是在通过了v1以后,发现v1到v2的距离在加上v1到v0的距离比v0直接到v2的距离要段,所以这一步操作也会把这个距离给替换掉。Pathmatrix[w]  = k ,这行代码是说,要到w这个节点,需要通过k点。

剩下的步骤,继续执行这个循环,直到遍历完所有的节点。结束后,Pathmatrix 存储的是节点路径,ShortPathTab 存储节点路径的距离,可以根据这两个变量得到v0到所有节点的最短距离。

至此算法结束。欢迎来拍砖。

转载于:https://my.oschina.net/nicozhang/blog/357471

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值