5种经典最短路径算法联系与区别

5种经典最短路径算法联系与区别

\color{red}{}
  5种经典路径算法指的是 D i j k s t r a , F l o y d , 贝 尔 曼 福 德 , S P F A , A ∗ 算 法 \color{red}{Dijkstra,Floyd,贝尔曼福德,SPFA,A* 算法} Dijkstra,Floyd,SPFAA(出场顺序根据文章思路进行),本文不再赘述其各自的概念与内容(不清楚的请先查阅其他大佬的博客),按本人理解从中发觉其中的联系与区别。


  •     首先最经典的 D i j k s t r a \color{red}{Dijkstra} Dijkstra算法,我们通过其算法过程,可以概括为贪婪思想,逐步扩展,为什么这么说,根据算法过程,例如A点为起点,那么就有一个列表即A到各点的距离,从整体看每次都在更新列表以达到最小目的。 那是如何更新呢,分两步:
        一是从每次列表中取最小的点(记为M)即为A到此点M的最短距离,取最小即贪婪思想。
        二是以此找出最小的点为桥接点,通过比较A -> 终点 还是A->M->终点 大小进行“松弛“,(常见的松弛就是比较个大小而已),松弛完毕每个点,则更新列表值一次。 下次更新从更新后的剩余点中找最小。直到遍历所有点结束
      因为每次更新都是以第一步中的最小值为基础,所以这也是为什么此算法只能用于正值的根本所在,简单来说就是算法特点不会重回此点再去松弛,所以有负值时出现非最佳结果。

    联 系 点 : \color{blue}{联系点:} 那么我们可以看到Dijkstra 只能正权是因为不能回点松弛,那么为什么我非要取最小值为桥接点呢,我找一种办法让他可以回点松弛不就可以是负权了嘛,所以后来又产生了另一种算法叫贝尔曼福德。


  •     贝 尔 曼 福 德 \color{red}{贝尔曼福德} 利用了最短路径的边特点,什么特点呢,即假设无回路下有N个点,查找最短路径最多松弛N-1次就有结果了,即把每个点都通过一遍。那贝尔曼福德咋做的呢,直接循环N-1次,每次都对各边松弛一下,这样绝对不会漏掉,简单粗暴,循环完N-1,我再来一遍松弛,发现有边还在变化,这是怎么了,这不符合我们的背景啊,所以出现这种情况即出现了回路,所以贝尔曼也是通过这个方法判断是否有回路存在。

    联 系 点 : \color{blue}{联系点:} 有人应该又看出了,我每次都松弛每个边,明明好多边都不用变的啊,这不浪费时间嘛,有没有一种办法能够精准定位松弛情况呢,所以又出现了一种算法解决这个问题,就是SPFA。


  •     S P F A \color{red}{SPFA} SPFA算法一般博客中都说这个叫做队列优化后的贝尔曼,为啥这么说? 其实很简单,所谓的队列优化就是用了广度优先算法BFS思想,BFS一般是用队列来实现的,好了有了这个能干嘛,假如我们还是那个A点到各点距离的列表,我们不找最小了,我们从起点开始找他的连通节点,连通节点松弛了,说明什么,说明连通节点松弛了,那么连通节点的连通节点有可能需要松弛啊,这里有点绕,简单来说就是我是小B和小C的哥,小D的叔,我娶了小B的姐,小B得换姐夫,小C还是哥,小D没他啥事 肯定还是叔,一个道理,根据这个特点,我们可以广度遍历的时候,每次都去判断是否去松弛 松弛过的点 所连通的点,这个操作就是通过队列来实现。

    联 系 点 : \color{blue}{联系点:} 好了,现在已经说了三个算法了,我们从宏观会发现,找到最短路径怎么也得遍历到所有的点或者说边才能找到,那么有没有一种直接关心遍历问题而产生的算法呢,Floyd即为此。


  •     F l o y d \color{red}{Floyd} Floyd又称为插点法,为啥,他就是关心你到最短路径是否考虑到了存在的所有点,从动态规划的角度,可以从小到大,比如有N个点,一开始我就只考虑起点与终点之间就一个点的时候,很好算松弛一下是吧,那么往下考虑有俩点呢,在之前基础上再松弛一下,好了考虑到所有点之后,最短路径就出来了。思想简单,代码更简单。自行查找。

    联 系 点 : \color{blue}{联系点:} 最后一个A算法,与前边都不同,他属于启发式,但是并不无联系,他最大联系在于与Dijlstra的联系,Dijlstra应用的是实际距离作为判断数据,他无方向性的去判断最小,贪婪前行,性能肯定比有方向的更差,那有什么办法让算法向结果方向进行呢,即A


  •     A ∗ \color{red}{A*} A之所以叫启发式,是因为他有一个很特别的东西叫评估函数,f=g+h, g可以看作Dijlstra中的实际距离,h为评估距离,而A比较的依据是f值,Dijlstra依据是g值,所以很容易看到联系,当h为0时,两者相等,A退化为Dijlstra,h=0,说明没有方向性, 那h是啥,咋确定,一般应用曼哈顿距离,就是X,Y各轴相差的绝对值和。 A具体算法不再赘述,靠理解来说就是Dijlstra判断最小用g值,松弛更新也用g值判断, 而A判断最小用f值,松弛更新用g值判断。 本质区别就是f含有向终点方向的程度值,使得朝向终点找最短路径,无疑更为快速。

以上,认真理解的小伙伴,应该已经看到了他们的区别与联系。简单总结:
  • Dijkstra 适用范围:单源 正权 无回路 方式:贪婪无向扩展
  • 贝尔曼 适用范围:单源 正负权 无回路 方式:暴力松弛
  • SPFA 适用范围:单源 正负权 无回路 方式:更精确去松弛的贝尔曼
  • Floyd 适用范围:多源 正负权 无回路 方式:遍历考虑所有点
  • A* 适用范围:点对 正权 无回路 方式:贪婪评估有向扩展

所有以上算法 都是静态图,即点不会动的去查找, 目前更高级的人工智能机器人都需要动态查找路径,D* ,D* Lite之类的算法产生,有兴趣的同学继续深入~。
  • 14
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值