正确理解Dijkstra(迪杰斯特拉)算法

下面给出一张在各大计算机网络教材中使用的经典例图。


我们的目的是求出A到各点的最短路径,初始集合U={A,B,C,D,E,F}。取元素的规则是取当前A到各点最短且没被取过的点(即在U中的点)


我们一开始从U中取出A,并更新各点距离。当前A到D=1,A到B=2,A到另外的点的距离是无穷大,所以我们取出D。



取出D后A到各点的距离。当A打算A->D->B作为A到B的最小路径3的时候,发现更新不了,因为原来AB是2,更短,更新失败。这里B、E两点可以任取。我们取E。



到达E点后,A到各点的最短距离如下图所示。成功更新C点的最短距离为1+1+1=3。这里就是重点了。发现A到B最短,所以我们直接取B了!



下面给出取B后的A到各点的距离,B视图用2+3去更新C,发现更新不了。这里就取C了。取了C试图带着3+5=8去更新F,发现更新不了。最后取出F,所有点都取完了,A到每个点的最短距离都已经显示出来了。



接下来是原理剖析。


首先明白一点,我们不是一个个点走下去的,而是一个个点取下去的。如果你认为Dijkstra算法是靠走的,那么你在取完E后再取B的这个过程十分疑惑了。


此外为什么要以这种形式取呢?其实大可不必。上面的Dijkstra算法是优化过的Dijkstra算法。最原始的Dijkstra算法是任意从U中取一个点,然后以此更新另外不管取过没取过的所有的点。


我们优化过的算法就很聪明了,我们取过的点,我们就不再更新他了!可是问题来了,我们不更新他,最终的出来的结果不会错吗?当然会错,所以我们采取的措施是取元素的规则是取当前A到各点最短且没被取过的点(即在U中的点)。为什么这样的取法就可以规避更新我们取过的点呢?其实从最小开始更新不会错,但是假如说你不是这样一个取法,你可能会发现你会率先取到大的值,但是你当你取的小的数,但是因为大的数已经取过了,你更新不了他了,但是事实上他有更小的解,这个时候就错了。详细可以看我的-深入理解Dijkstra(迪杰斯特拉)算法-的解析部分:http://blog.csdn.net/qq_36523667/article/details/78779272

  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值