求最短路的多种方法比较及应用
《挑战程序设计竞赛》里面介绍了三种方法: Bellman-Ford、Dijkstra and Floyd
三者区别也都很明显:
Bellman-Ford:
求单源最短路,可以判断有无负权回路(若有,则不存在最短路), 时效性较好,时间复杂度O(VE)。
Bellman-Ford算法是求解单源最短路径问题的一种算法。
单源点的最短路径问题是指: 给定一个加权有向图G和源点s,对于图G中的任意一点v,求从s到v的最短路径。
与Dijkstra算法不同的是,在Bellman-Ford算法中,边的权值可以为负数。 设想从我们可以从图中找到一个环路(即从v出发,经过若干个点之后又回到v)且这个环路中所有边的权值之和为负。那么通过这个环路,环路中任意两点的最短路径就可以无穷小下去。如果不处理这个负环路,程序就会永远运行下去。 而Bellman-Ford算法具有分辨这种负环路的能力。
Dijkstra:
求单源、无负权的最短路。时效性较好,时间复杂度为O(V*V+E)。 源点可达的话,O(V*lgV+E*lgV)=>O(E*lgV)。 当是稀疏图的情况时,此时E=V*V/lgV,所以算法的时间复杂度可为O(V^2) 。若是斐波那契堆作优先队列的话,算法时间复杂度,则为O(V*lgV + E)。
Floyd:
求多源、无负权边的最短路。用矩阵记录图。时效性较差,时间复杂度O(V^3)。 Floyd-Warshall算法(Floyd-Warshall algorithm)是解决任意两点间的最短路径的一种算法,可以正确处理有向图或负权的最短路径问题。
Floyd-Warshall算法的时间复杂度为O(N^3),空间复杂度为O(N^2)。
Floyd-Warshall的原理是动态规划: 设Di,j,k为从i到j的只以(1..k)集合中的节点为中间节点的最短路径的长度。 若最短路径经过点k,则Di,j,k = Di,k,k-1 + Dk,j,k-1; 若最短路径不经过点k,则Di,j,k = Di,j,k-1。 因此,Di,j,k = min(Di,k,k-1 + Dk,j,k-1 , Di,j,k-1)。
在实际算法中,为了节约空间,可以直接在原来空间上进行迭代,这样空间可降至二维。 Floyd-Warshall算法的描述如下: for k ← 1 to n do for i ← 1 to n do for j ← 1 to n do if (Di,k + Dk,j < Di,j) then Di,j ← Di,k + Dk,j; 其中Di,j表示由点i到点j的代价,当Di,j为 ∞ 表示两点之间没有任何连接。
后来,我看Bellman-Ford的队列优化,SPFA(Shortest Path Faster Algorithm )。
SPFA:
是Bellman-Ford的队列优化,时效性相对好,时间复杂度O(kE)。(k<<V)。
与Bellman-ford算法类似,SPFA算法采用一系列的松弛操作以得到从某一个节点出发到达图中其它所有节点的最短路径。所不同的是,SPFA算法通过维护一个队列,使得一个节点的当前最短路径被更新之后没有必要立刻去更新其他的节点,从而大大减少了重复的操作次数。
SPFA算法可以用于存在负数边权的图,这与dijkstra算法是不同的。
与Dijkstra算法与Bellman-ford算法都不同,SPFA的算法时间效率是不稳定的,即它对于不同的图所需要的时间有很大的差别。
在最好情形下,每一个节点都只入队一次,则算法实际上变为广度优先遍历,其时间复杂度仅为O(E)。另一方面,存在这样的例子,使得每一个节点都被入队(V-1)次,此时算法退化为Bellman-ford算法,其时间复杂度为O(VE)。
SPFA算法在负边权图上可以完全取代Bellman-ford算法,另外在稀疏图中也表现良好。但是在非负边权图中,为了避免最坏情况的出现,通常使用效率更加稳定的Dijkstra算法,以及它的使用堆优化的版本。通常的SPFA算法在一类网格图中的表现不尽如人意。
转载于:https://www.cnblogs.com/Roni-i/p/8352269.html
求最短路的多种方法比较及应用相关推荐
- 求字符串长度的多种方法
目录 标准简洁快速法 创建临时变量 --计数器的方法 不许创建临时变量 --递归的方法 运用指针运算 --指针减指针的方法 本文涉及知识点:求字符串长度用 strlen ...
- C语言求最大公约数3种方法
该博文为原创文章,未经博主同意不得转载,如同意转载请注明博文出处 本文章博客地址:https://cplusplus.blog.csdn.net/article/details/105163610 C ...
- 【君义精讲】多种方法求斐波那契数列
概念 斐波那契数列(Fibonacci sequence),又称黄金分割数列,因数学家莱昂纳多·斐波那契(Leonardo Fibonacci)以兔子繁殖为例子而引入,故又称为"兔子数列&q ...
- matlab怎么求三次微分,matlab课设三阶微分方程多种方法求解.doc
matlab课设三阶微分方程多种方法求解 目录 一.课程设计题目及意义 -------- 1 页 二.课程设计任务及要求 --------2 页 三.课程设计详细过程及结果 --------3至10页 ...
- 编程笔试(解析及代码实现):多种方法求所有小于n的质数的个数
编程笔试(解析及代码实现):多种方法求所有小于n的质数的个数 目录 题目描述 代码实现 题目描述 多种方法求所有小于n的质数的个数 T1.穷举法:根据定义循环判断该数除以比他小的每个自然数(大于1), ...
- C语言|求最大公约数和最小公倍数多种方法
在开始之前我们先了解下什么是最大公约数和最小公倍数: 例如有两个数:a 和b 最大公约数用gcd表示,最小公倍数用lcm表示. 1.最大公约数就意味着能同时被a和b整除,即a%gcd==0 & ...
- AcWing 845. 八数码(3阶数字华容道):bfs求最短路,状态表示困难
文章目录 题目 题目分析 题目 题目链接:AcWing 845. 八数码(数字华容道) 在一个3×3的网格中,1~8这8个数字和一个"x"恰好不重不漏地分布在这3×3的网格中. 例 ...
- python中质数的表达方式_python求质数的3种方法
本文为大家分享了多种方法求质数python实现代码,供大家参考,具体内容如下 题目要求是求所有小于n的质数的个数. 求质数方法1: 穷举法: 根据定义循环判断该数除以比他小的每个自然数(大于1),如果 ...
- 智科模式识别期末大课设:多种方法对数据集进行手写数字识别(数据集:MINIST)
0结课作业内容 (1)程序编写及报告. 请大家下载70000个样本的MNIST数据集("手写体数字70000.zip",28*28像素),60000个用于训练,10000个用于测试 ...
- python求素数积_python求质数的3种方法
本文为大家分享了多种方法求质数python实现代码,供大家参考,具体内容如下 题目要求是求所有小于n的质数的个数. 求质数方法1: 穷举法: 根据定义循环判断该数除以比他小的每个自然数(大于1),如果 ...
最新文章
- 网络推广团队介绍网站页面优化时需要注意什么细节?
- 总结:C#中跨窗体传值的几种方法
- 根据文件扩展名得到文件对应该类型Icon方法
- jooq和jdbc_将jOOQ与JDBC比较
- Linux 下查看线程信息
- oracle 取记录最大的那条记录_新记录!国内跨高速铁路最大、吊装高度最高的钢横梁顺利吊装到位...
- HDOJ 1019 Least Common Multiple (数论)
- Altium Designer数码管字体、镂空字体
- 剖析《Linux 平均负载:解开谜团》
- yolov3识别的类别_Yolo3 如何只识别一个类别
- 并发和并行的区别(图解)
- 长城汽车携旗下哈弗、欧拉、长城皮卡及WEY登陆北京车展
- 1、高等数学 —求和运算法则
- 听说最近知识变现,测一测程序员的知识广度?
- 有关textField左视图leftView和书写位置的设置
- 追求成功三要诀 文 | 刘东华
- camunda 流程执行追踪_Camunda流程调用梳理
- Switch NS 通过华硕梅林路由DNSMASQ屏蔽任天堂服务器
- 托管调试助手 “LoaderLock“:“正尝试在 OS 加载程序锁内执行托管代码。不要尝试在 DllMain 或映像初始化函数内运行托管代码,这样做会导致应用程序挂起。”
- 将物流行业送往智能时代,菜鸟网络的配送车已经上路了
热门文章
- python 读取文件名列表_python 读取指定文件夹下所有文件名
- Sum nyoj 欧拉定理简单运用(数论入门)
- 【2019JXCPC省赛:H】Rng(找规律+逆元)
- node.js 微信小程序 部署服务器_微信小程序云开发如何上手
- redis统计用户日活量_【赵强老师】Redis案例分析:用setbit统计活跃用户
- mysql-8.0.26-winx64 的下载与安装教程
- 开源嵌入式linux,移植开源软件到嵌入式Linux系统技术攻略
- 汇编程序实现快速排序_用Python 3实现快速排序和插入排序代码详解
- XLNet 和BERT的区别是什么?
- 非递归二叉树的序列打印