dijkstra 算法为什么高效?

最短路径算法中,dijkstra(i,j,k 颇有遍历意味) 算法时间效能很好,而 floyd,bellman-ford 算法则优在处理负权重。但这是为什么?

从算法过程看,dijkstra 算法确定了某点最短路径后,它就不会再因 “松弛” 而变得更短,而别的两个算法则必须遍历完所有可能的 “松弛” 点才能确定。这个解释有点循环因果了,算法导致了高效,而高效的是算法。可这背后蕴含着什么大道理?

dijkstra 算法展示的是一个 “自然界自然发生的自然过程”,是一个熵增过程。不提 “贪婪策略” 这种名词,看几个自然过程来理解,河水泛滥或农村浇地过程,爆炸过程都可以展现 dijkstra 算法的执行。世间万物,如果任其自然发展而不管,这些个过程其实都是 dijkstra 算法过程的体现。

客观上,每个节点距离源 S 可能不止一条路径,但肯定都有至少一条最短路径,设这些最短路径为 Di,Dj,Dk,Ds,Dt,Dr,Da,… 中肯定有一个从小到大的序,即它们也能排序,dijkstra 算法就是依次寻找每个节点距离源 S 最短距离中最小那个的过程。

以爆炸距离,若一群节点分布在爆炸源周围,按照自然界最小作用量这种第一性原理,最先被波及的一定是距离爆炸源最短的,其次被波及的一定是次短的,以此类推。

把一张有向图按照节点和距离编码在一个二维坐标系里就一目了然了,反着看,从 dijkstra 的结果反推它的过程,这将是一个与 dijkstra 算法不同,但殊途同归的过程:
在这里插入图片描述

极坐标更适合编码 dijkstra 图,用不同半径的同心圆环表示距离,而不同夹角表示不同节点,最后从圆心往外爆,这才更像自然爆炸的过程。考虑到这种图不太容易画,用上面的平面直角坐标系替代了,道理一样。

dijkstra 算法高效的原因就在于它在执行过程中考虑到了这个 “每个节点最短路径亦有大小之分” 的自然序,dijkstra 算法求的就是 “每个节点最短路径的最小值”,在这个过程中自然也就排除了那些 “每个节点的非最短路径”,因为它们没有比较的资格。如果不考虑自然序,就只能硬比对,遍历所有可能的松弛空间,静待松弛不变后停止算法,而这就是 floyd,bellman-ford 等算法的过程。

floyd,bellman-ford 算法是个人为的过程,而不是自然的过程。floyd 算法的技巧在于如何高效折腾二维邻接矩阵,而 bellman-ford 算法的技巧则在于邻居交互的过程,何时交互,以及交互什么,所以人为过程是个熵减过程,虽然费劲,但也能处理非自然逻辑,比如负权重。

对于负权重的理解,如果它仅仅是一个度量,那可以统一加一个比最大负权重小 1 的数字的绝对值,就可以使用 dijkstra 算法,但事情没有这么简单,负权重并非只是一个度量,本文暂不谈,有空专门说下 bellman-ford 这种人为的熵减算法。

流体沿着最短路径,最先到达哪个就是哪个,这是 dijkstra 算法,而经理办公桌上有一堆报表,让工人拟合一份最佳收支方案,工人用图论建模,就要使用 floyd,bellman-ford 算法。

浙江温州皮鞋湿,下雨进水不会胖。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值