Bellman-Ford算法——为什么要循环n-1次?图有n个点,又不能有回路,所以最短路径最多n-1边。又因为每次循环,至少relax一边所以最多n-1次就行了!
单源最短路径
给定一个图,和一个源顶点src,找到从src到其它所有所有顶点的最短路径,图中可能含有负权值的边。
Dijksra的算法是一个贪婪算法,时间复杂度是O(VLogV)(使用最小堆)。但是迪杰斯特拉算法在有负权值边的图中不适用,Bellman-Ford适合这样的图。在网络路由中,该算法会被用作距离向量路由算法。Bellman-Ford也比迪杰斯特拉算法更简单。但Bellman-Ford的时间复杂度是O(VE),这要比迪杰斯特拉算法慢。(V为顶点的个数,E为边的个数)
算法描述
输入:图 和 源顶点
输出:从src到所有顶点的最短距离。如果有负权回路(不是负权值的边),则不计算该最短距离,没有意义,因为可以穿越负权回路任意次,则最终为负无穷。
算法步骤
1.初始化:将除源点外的所有顶点的最短距离估计值 dist[v] ← +∞, dist[s] ←0;
2.迭代求解:反复对边集E中的每条边进行松弛操作,使得顶点集V中的每个顶点v的最短距离估计值逐步逼近其最短距离;(运行|v|-1次)
3.检验负权回路:判断边集E中的每一条边的两个端点是否收敛。如果存在未收敛的顶点,则算法返回false,表明问题无解;否则算法返回true,并且从源点可达的顶点v的最短距离保存在 dist[v]中。
关于该算法的证明也比较简单,采用反证法,具体参考:http://courses.csail.mit.edu/6.006/spring11/lectures/lec15.pdf
该算法是利用动态规划的思想。该算法以自底向上的方式计算最短路径。
它首先计算最多一条边时的最短路径(对于所有顶点)。然后,计算最多两条边时的最短路径。外层循环需要执行|V|-1次。
例子
一下面的有向图为例:给定源顶点是0,初始化源顶点距离所有的顶点都是是无穷大的,除了源顶点本身。因为有5个顶点,因此所有的边需要处理4次。
按照以下的顺序处理所有的边:(B,E), (D,B), (B,D), (A,B), (A,C), (D,C), (B,C), (E,D).
第一次迭代得到如下的结果(第一行为初始化情况,最后一行为最终结果):
当 (B,E), (D,B), (B,D) 和 (A,B) 处理完后,得到的是第二行的结果。
当 (A,C) 处理完后,得到的是第三行的结果。
当 (D,C), (B,C) 和 (E,D) 处理完后,得到第四行的结果。
第一次迭代保证给所有最短路径最多只有1条边。当所有的边被第二次处理后,得到如下的结果(最后一行为最终结果):
第二次迭代保证给所有最短路径最多只有2条边。我们还需要2次迭代(即所谓的松弛操作),就可以得到最终结果。
算法描述
为什么要循环V-1次?
答:因为最短路径肯定是个简单路径,不可能包含回路的,如果包含回路,且回路的权值和为正的,那么去掉这个回路,可以得到更短的路径如果回路的权值是负的,那么肯定没有解了.图有n个点,又不能有回路,所以最短路径最多n-1边。又因为每次循环,至少relax一边所以最多n-1次就行了。
算法导论上的伪代码:
BELLMAN-FORD(G, w, s)
1 INITIALIZE-SINGLE-SOURCE(G, s)
2 for i ← 1 to |V[G]| - 1
3 do for each edge (u, v) ∈ E[G]
4 do RELAX(u, v, w)
5 for each edge (u, v) ∈ E[G]
6 do if d[v] > d[u] + w(u, v)
7 then return FALSE
8 return TRUE
Bellman-Ford算法——为什么要循环n-1次?图有n个点,又不能有回路,所以最短路径最多n-1边。又因为每次循环,至少relax一边所以最多n-1次就行了!的更多相关文章
- Bellman - Ford 算法解决最短路径问题
Bellman - Ford 算法: 一:基本算法 对于单源最短路径问题,上一篇文章中介绍了 Dijkstra 算法,但是由于 Dijkstra 算法局限于解决非负权的最短路径问题,对于带负权的图就力 ...
- Bellman—Ford算法思想
---恢复内容开始--- Bellman—Ford算法能在更普遍的情况下(存在负权边)解决单源点最短路径问题.对于给定的带权(有向或无向)图G=(V,E),其源点为s,加权函数w是边集E的映射.对图G ...
- Dijkstra算法与Bellman - Ford算法示例(源自网上大牛的博客)【图论】
题意:题目大意:有N个点,给出从a点到b点的距离,当然a和b是互相可以抵达的,问从1到n的最短距离 poj2387 Description Bessie is out in the field and ...
- poj1860 bellman—ford队列优化 Currency Exchange
Currency Exchange Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 22123 Accepted: 799 ...
- uva 558 - Wormholes(Bellman Ford判断负环)
题目链接:558 - Wormholes 题目大意:给出n和m,表示有n个点,然后给出m条边,然后判断给出的有向图中是否存在负环. 解题思路:利用Bellman Ford算法,若进行第n次松弛时,还能 ...
- ACM/ICPC 之 最短路径-Bellman Ford范例(POJ1556-POJ2240)
两道Bellman Ford解最短路的范例,Bellman Ford只是一种最短路的方法,两道都可以用dijkstra, SPFA做. Bellman Ford解法是将每条边遍历一次,遍历一次所有边可 ...
- 34、在排序数组中查找元素的第一个和最后一个位置 | 算法(leetode,附思维导图 + 全部解法)300题
零 标题:算法(leetode,附思维导图 + 全部解法)300题之(34)在排序数组中查找元素的第一个和最后一个位置 一 题目描述 二 解法总览(思维导图) 三 全部解法 1 方案1 1)代码: / ...
- 36、有效的数独 | 算法(leetode,附思维导图 + 全部解法)300题
零 标题:算法(leetode,附思维导图 + 全部解法)300题之(36)有效的数独 前言 1)码农三少 ,一个致力于 编写极简.但齐全题解(算法) 的博主. 2)文末附赠 价值上百美刀 资料. 一 ...
- js中,for循环里面放ajax,ajax访问不到变量以及每次循环获取不到数据问题总结
想在点击"终端控制"的时候能够开启多个窗口对多个终端进行管理: /**提交事件**/ $("#terminalControl").bind("clic ...
随机推荐
- 函数indexOf()和lastIndexOf()
返回前面起第一个字符的位置indexOf(“字符”); 它是从前面开始数(从左边开始数),而且只找第一个,然后返回该字符的位置,索引号都是从0开始的.返回的是个数值. var txt = “abcde ...
- sqlserver 中通配符%和_的使用
--以a开头的数据 SELECT * FROM BCUSTOMER_MZN WHERE CST_NAME LIKE 'A%' --以Z结尾的数据 SELECT * FROM BCUSTOMER_MZN ...
- R语言 平滑连接
参考自 153分钟 使用平滑曲线,沿着X轴从左向右的顺序依次连接,可以使用spline样条函数线. x = 1:5 y = c(1,3,4,2.5,2) plot(x,y) sp = spline(x ...
- vuex 源码:深入 vuex 之辅助函数 mapState
前言 当一个组件要获取多个 state 的时候,声明计算属性就会变得重复和冗余了.我们可以使用到辅助函数 mapState 来更快更简洁地生成计算属性. 所以我们得清楚,mapState 的作用就是帮 ...
- 第 3 章 镜像 - 020 - 搭建本地 Registry
Docker Hub 虽然非常方便,但还是有些限制,比如: 需要 internet 连接,而且下载和上传速度慢. 上传到 Docker Hub 的镜像任何人都能够访问,虽然可以用私有 reposito ...
- js插件---bootstrap-datepicker.js是什么
js插件---bootstrap-datepicker.js是什么 一.总结 一句话总结:选择时间的插件 时间选择插件 1.datepicker如何默认选择当前天? 直接给datepicker对应的i ...
- legend2---开发日志6(后端和前端如何相互配合(比如php,js,元素状态和数据改变))
legend2---开发日志6(后端和前端如何相互配合(比如php,js,元素状态和数据改变)) 一.总结 一句话总结:php给元素初始状态,js根据这个状态做初始化和后续变化,使用vue真的很方便( ...
- layui 下拉框不显示解决方法
添加以下代码 layui.use('form', function(){ var form = layui.form; form.render(); });
- 本地广播的简单示例 --Android开发
1.局部通知管理器LocalBroadcastManager,用于同一个应用中不同组件之间发送广播.由于是在同应用中发送广播,所以使用它安全性.效率也会提高. 2.本例实现简单的发送本地广播的案例 点 ...
- Spring Boot之默认连接池配置策略
注意:如果我们使用spring-boot-starter-jdbc 或 spring-boot-starter-data-jpa “starters”坐标,Spring Boot将自动配置Hikari ...