• 最短路径算法
    • 1.Dijkstra算法
    • 2.Bellman-Ford算法
    • 3.SPFA算法
    • 4.Floyd算法
  • 几种最短路径算法的对比
    • Dijkstra算法、Bellman-Ford算法和SPFA算法的对比
    • Dijkstra算法和Floyd算法的对比

最短路径算法

  • 单源最短路算法:已知起点,求到达其他点的最短路径。
            常用算法:Dijkstra算法、Bellman-Ford算法、SPFA算法。
  • 多源最短路算法:求任意两点之间的最短路径。
            常用算法:Floyd算法。

1.Dijkstra算法

迪杰斯特拉算法(Dijkstra)是寻找从一个顶点到其余各顶点最短路径的算法,解决的是有权图中最短路径问题。迪杰斯特拉算法主要特点是从起始点开始,采用贪心算法的策略,每次遍历到始点距离最近且未访问过的顶点的邻接节点,直到扩展到终点为止。
        处理问题:单源、无负权、有向图、无向图最短路径。
        不能使用的情况:边中含有负权值(无法判断)。
        主要特点:以起始点为中心向外层层扩展,直到扩展到终点为止。
        算法过程:V为顶点集合,分为两组S和U。其中,S为已求出的顶点的集合(初始时只含有源点V0),U为尚未确定的顶点集合,源点到各个顶点最短路径的距离结果存在dist[]中。
                        1.初始化:S只包含源点,U包含除V中S以外的其他点;
                        2.选择:从U中选取一个距离源点最近的顶点u加入S;
                        3.更新:修改u的后继顶点的最短路径长度;
                        4.重复步骤2和3直到所有顶点都包含在S中。
       举例说明:图中有A、B、C、D、E五个顶点,其中A为源顶点,寻找A到其他各顶点的最短路径。
                        Step1:V包含A、B、C、D、E五个点,S只包含源点A,U包含V中除S以外的其他点,计算U中各点到源点的距离发现距源点最近的顶点是B;                        Step2:将距源点最近的顶点B移入S中,S包含A、B,U包含C、D、E,再次计算U中各点到源点的距离发现距源点最近的顶点是C;                        Step3:再次将距源点最近的顶点C移入S中,S包含A、B、C,U包含D、E,再次计算U中各点到源点的距离发现距源点最近的顶点是E;                        Step4:再次将距源点最近的顶点E移入S中,S包含A、B、C、E,U包含D,再次计算U中各点到源点的距离发现距源点最近的顶点是D;                        Step5:再次将距源点最近的顶点D移入S中,S包含A、B、C、E、D,U为空,算法结束,得到的dist[]中的结果就是A到其他各顶点的最短距离。

2.Bellman-Ford算法

贝尔曼-福特算法(Bellman–Ford)是求解单源最短路径问题的一种算法,它的原理是对图进行次松弛操作,得到所有可能的最短路径。其算法可以进行若干种优化,提高了效率。
       基本思想: Bellman-Ford的思想和Dijkstra很像,其关键点都在于不断地对边进行松弛,而最大的区别就在于前者能作用于负边权的情况。其实现思路是在求出最短路径后,判断此刻是否还能对便进行松弛,如果还能进行松弛,便说明还有负边权的边。
       处理问题:单源、可有负权、有向图、无向图最短路径。
       算法过程:1.初始化:初始化所有的点,每一个点保存一个值,表示源点到这个点的距离其他点的值设为无穷大;
                        2.迭代求解:进行循环,从1到n-1,进行松弛计算;
                        3.检验负权回路:遍历所有边,如果的d[v]>d[u]+w(u,v)存在,则有从源点可达的权为负的回路。
       边的松弛操作:如下图所示,d[v]、d[u]是目前s到v、u的最短距离,关注边<u,v>能否改善d[v]的值。如果if(d[u]+w<d[v])成立,原有的d[v]路线将被s→\rightarrow→u→\rightarrow→v代替,这就是边<u,v>的松弛操作。

3.SPFA算法

SPFA 算法是Bellman-Ford算法的队列优化算法的别称,通常用于求含负权边的单源最短路径,以及判负权环,它采用一系列的松弛操作以得到从某一个节点出发到达图中其它所有节点的最短路径。
       处理问题:单源、可有负权、有向图、无向图最短路径(自身其实无法处理负权)
       算法思想:设立一个队列用来保存待优化的点,优化时每次取出队首结点u,并且用u点当前的最短路径估计值对u点所指向的结点v进行松弛操作,如果v点的最短路径估计值有所调整,且v点不在当前的队列中,就将v点放入队尾。这样不断从队列中取出结点来进行松弛操作,直至队列空为止。

4.Floyd算法

弗洛伊德算法(Floyd)又称为插点法,是一种利用动态规划的思想寻找给定的加权图中多源点之间最短路径的算法。Floyd算法适用于APSP(All Pairs Shortest Paths,多源最短路径),稠密图效果最佳,边权可正可负。此算法简单有效,由于三重循环结构紧凑,对于稠密图,效率要高于执行|V|次Dijkstra算法,也要高于执行|V|次SPFA算法。
       处理问题:多源、可有负权、有向图、无向图最短路径。
       优点:容易理解,可以算出任意两个节点之间的最短距离,代码编写简单。
       缺点:时间复杂度比较高,不适合计算大量数据。
       算法过程:1.从任意一条单边路径开始,所有两点之间的距离是边的权,用邻接矩阵G表示,如果两点之间没有边相连,则权为无穷大;
                        2.对于每一对顶点i和j,看看是否存在一个顶点k使得从i到k再到j比已知的路径更短。G[i][j] = min( G[i][j], G[i][k]+G[k][j] ),如果G[i][j]的值变小,定义一个矩阵D用来记录所插入点的信息,则D[i][j]=k。
                                      forkinrange(self.V):for{_{}}{_{}}{_{}}{_{}}{_{}}{_{}}{_{}}{_{}}k{_{}}{_{}}{_{}}{_{}}{_{}}{_{}}{_{}}{_{}} in {_{}}{_{}}{_{}}{_{}}{_{}}{_{}}{_{}}{_{}}range(self.V):for​​​​​​​​k​​​​​​​​in​​​​​​​​range(self.V):
                                             foriinrange(self.V):for{_{}}{_{}}{_{}}{_{}}{_{}}{_{}}{_{}}{_{}}i{_{}}{_{}}{_{}}{_{}}{_{}}{_{}}{_{}}{_{}} in {_{}}{_{}}{_{}}{_{}}{_{}}{_{}}{_{}}{_{}}range(self.V):for​​​​​​​​i​​​​​​​​in​​​​​​​​range(self.V):
                                                    forjinrange(self.V):for{_{}}{_{}}{_{}}{_{}}{_{}}{_{}}{_{}}{_{}}j{_{}}{_{}}{_{}}{_{}}{_{}}{_{}}{_{}}{_{}} in {_{}}{_{}}{_{}}{_{}}{_{}}{_{}}{_{}}{_{}}range(self.V):for​​​​​​​​j​​​​​​​​in​​​​​​​​range(self.V):
                                                           ifself.G[i][k]+self.G[k][j]<self.G[i][j]:if{_{}}{_{}}{_{}}{_{}}{_{}}{_{}}{_{}}{_{}}self.G[i][k]{_{}}{_{}}{_{}}{_{}}{_{}}{_{}}{_{}}{_{}}+self.G[k][j]<self.G[i][j]:if​​​​​​​​self.G[i][k]​​​​​​​​+self.G[k][j]<self.G[i][j]:
                                                                  self.G[i][j]=self.G[i][k]<self.G[k][j]self.G[i][j]{_{}}{_{}}{_{}}{_{}}{_{}}{_{}}{_{}}{_{}}={_{}}{_{}}{_{}}{_{}}{_{}}{_{}}{_{}}{_{}}self.G[i][k]<self.G[k][j]self.G[i][j]​​​​​​​​=​​​​​​​​self.G[i][k]<self.G[k][j]
                                                                  self.D[i][j]=self.D[i][k]self.D[i][j]{_{}}{_{}}{_{}}{_{}}{_{}}{_{}}{_{}}{_{}}={_{}}{_{}}{_{}}{_{}}{_{}}{_{}}{_{}}{_{}}self.D[i][k]self.D[i][j]​​​​​​​​=​​​​​​​​self.D[i][k]
       举例说明:图中有1、2、3、4、5五个顶点,寻找任意两点间的最短路径。矩阵G为任意两点间的权值邻接矩阵,矩阵D为用来记录所插入点的标号。
                        Step1:初始化矩阵G、D,G初始化为任意两点间的距离,若两点间没有直线相连则用无穷大表示;D初始化为任意两点间的终点标号。                        Step2:更新矩阵G、D,看有没有任意两点经过0之后比原来的路径更短,有的话G中对应的元素更新为更小的值,D中对应的元素更新为同一行第0列的元素。                        Step3:继续更新矩阵G、D,看有没有任意两点经过1之后比原来的路径更短,有的话G中对应的元素更新为更小的值,D中对应的元素更新为同一行第1列的元素。                        Step4:继续更新矩阵G、D,看有没有任意两点经过2之后比原来的路径更短,有的话G中对应的元素更新为更小的值,D中对应的元素更新为同一行第2列的元素。                        Step5:继续更新矩阵G、D,看有没有任意两点经过3之后比原来的路径更短,有的话G中对应的元素更新为更小的值,D中对应的元素更新为同一行第3列的元素。                        Step6:继续更新矩阵G、D,看有没有任意两点经过4之后比原来的路径更短,有的话G中对应的元素更新为更小的值,D中对应的元素更新为同一行第4列的元素。算法结束,得到的G4{G_{4}}G4​为任意两点间的最短距离,D4{D_{4}}D4​为任意两点间最短路径间的信息。

几种最短路径算法的对比

Dijkstra算法、Bellman-Ford算法和SPFA算法的对比

  • Dijkstra算法无法判断含负权边的图的最短路径,Bellman-Ford算法优于Dijkstra算法的方面是边的权值可以为负数、实现简单,缺点是时间复杂度过高。
  • SPFA算法在负边权图上可以完全取代Bellman-Ford算法,另外在稀疏图中也表现良好。但是在非负边权图中,为了避免最坏情况的出现,通常使用效率更加稳定的Dijkstra算法,以及它的使用堆优化的版本。
  • 与Dijkstra算法与Bellman-Ford算法都不同,SPFA的算法时间效率是不稳定的,即它对于不同的图所需要的时间有很大的差别。

Dijkstra算法和Floyd算法的对比

  • Dijkstra算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径。
  • Floyd算法是多源最短路径算法,用于计算任意两点间的最短路径。
  • Dijkstra算法是基于贪心算法的思想,从起点出发逐步找到通向终点的最短距离;而Floyd算法是基于动态规划的思路,通过循环迭代的方法同时找出任意两个顶点间的最短距离。

求解两点间最短路径的算法相关推荐

  1. 变分法求解两点间直线距离最短

    变分法求解两点间直线距离最短,问题很小,意义很大.

  2. 迪杰斯特拉算法 两点间最短路径的选择

    百度首页 登录 注册 新闻网页贴吧知道音乐图片视频地图百科文库 首页 分类 艺术 科学 自然 文化 地理 生活 社会 人物 经济 体育 历史 特色百科 历史上的今天 数字博物馆 史记·2015 城市百 ...

  3. C语言实现Dijkstra算法(求解两点之间最短路径问题)

    文章目录 含有约束条件下的最短路径问题 程序框图及变量说明 程序框图 算法解释 所用数据 代码实现 运行结果 含有约束条件下的最短路径问题 C语言实现最优路径算法(有限时间约束条件下的算法模型) 程序 ...

  4. matlab求任意点最短路径,【最短路】求两点间最短路径的改进的Dijkstra算法及其matlab实现...

    代码来源:<图论算法及其matlab实现>(北京航空航天出版社) P18 书中提出了基于经典Dijkstra算法改进的两种算法. 其中算法Ⅱ的效率较高. 代码如下: 1 function ...

  5. python两点之间最短距离_最短路径(图中两点间最短路径)

    packagecom.cn.datastruct;importjava.util.Scanner;//最短路径求解 public classDistMin {static classGraphMatr ...

  6. 求两点之间最短路径-Dijkstra算法

     Dijkstra算法 1.定义概览 Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止.D ...

  7. 二叉树任意两点间最短路径(利用栈-找公共祖先,不需要建立二叉树)

    代码: #include<bits/stdc++.h> using namespace std;int main() {int T;cin>>T;while(T--){int ...

  8. 两点之间最短路径:弗洛伊德算法

    弗洛伊德算法是计算无向有权图中两点间最短路径的算法,复杂度为O(n^3).其思路是将两点间距离分为过(指定的)第三点或是不过,然后取它们的最小值,如此循环就可以得到两点之间真正的最小值. void f ...

  9. AOJ GRL_1_C: All Pairs Shortest Path (Floyd-Warshall算法求任意两点间的最短路径)(Bellman-Ford算法判断负圈)

    题目链接:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_1_C All Pairs Shortest Path Input ...

最新文章

  1. mysql 数据库快照迁移_快照方式备份mysql 数据库
  2. 迁移学习(Transfer learning)、重用预训练图层、预训练模型库
  3. spring整合mybatis(入门级简单教程3)--获取sqlSession对象
  4. Enterprise Library: Configuration Application Block应用向导篇, Part 1
  5. Java字符串格式化
  6. shell常见的文件属性检查
  7. python对浏览器的常用操作有哪些_Python Selenium中对象常用操作方法
  8. 微信小程序 全局变量异步函数_微信小程序制作简述
  9. Bigpipe---FaceBook使用的页面加载技术
  10. SFP光模块基本概念及使用注意事项详解
  11. Sqlce与SQL Server2000/2005数据转换程序
  12. Oracle毙掉JavaOne
  13. python批量_Python学习第九十三天:Python批量处理图片
  14. 江湖不再平静---51CTO学院停服公告
  15. 马斯克:全力支持狗狗币主要持有者出售货币 持仓太集中是问题
  16. 潜龙号开启水下机器人_揭秘我国自主水下机器人“潜龙二号”
  17. 小米路由器3c 虚拟服务器,小米路由器怎么设置_小米路由器3c设置教程-WIFI之家...
  18. Menhera酱全套表情包
  19. 拥有阿里云免费ssl证书后,如何部署
  20. 懂球帝Android客户端WebView优化之路

热门文章

  1. iOS渐变视图动画库、腰杆、音频水滴水波手势、多种对话框、四级展开效果等源码
  2. SQLZOO 练习题 6 JOIN
  3. 【基础】Linux 常用操作
  4. 一文带你走进CI/CD
  5. “智造”转型:IBM协助福耀玻璃抢占市场先机
  6. React 组件封装之 Tree 树形控件
  7. #css 盒子div属性
  8. 单卡就能运行AI画画模型,小白也能看懂的教程来了,还有100万卡时免费NPU算力可用丨昇思MindSpore...
  9. 此计算机将网络限制为,解决win7无法连接wifi提示“此计算机当前已将连接限制为...”的方法...
  10. python爬虫 京东关键词搜索商品及具体参数和评论