算法系列——贝尔曼福特算法(Bellman-Ford)
本系列旨在用简单的人话讲解算法,尽可能避免晦涩的定义,读者可以短时间内理解算法原理及应用细节。我在努力!
本篇文章编程语言为Python,供参考。
贝尔曼福特算法(Bellman-Ford)
典型最短路径算法,用于计算一个节点到其他节点的最短路径。(Dijkstra算法也是)
基本原理:逐遍的对图中每一个边去迭代计算起始点到其余各点的最短路径,执行N-1遍,最终得到起始点到其余各点的最短路径。(N为连通图结点数)
与迪杰斯特拉算法的区别:
1. 迪杰斯特拉算法是借助贪心思想,每次选取一个未处理的最近的结点,去对与他相连接的边进行松弛操作;贝尔曼福特算法是直接对所有边进行N-1遍松弛操作。
2. 迪杰斯特拉算法要求边的权值不能是负数;贝尔曼福特算法边的权值可以为负数,并可检测负权回路。
名词解释:
1. 松弛操作:不断更新最短路径和前驱结点的操作。
2. 负权回路:绕一圈绕回来发现到自己的距离从0变成了负数,到各结点的距离无限制的降低,停不下来。
1. 邻接矩阵构建
基本用途:用一个二维数组存放两两结点之间的距离或权值。
2. 算法实现
3. 最短路径的寻找
同Dijkstra算法,准备一路径数组,更新时记录前驱结点。(较为简单,直接看也能看懂,不太懂可以翻阅之前Dijkstra算法那篇博客(算法系列——迪杰斯特拉算法(Dijkstra))
4. 优化
1. 提前跳出
2. 队列优化
见SPFA算法,见另一篇博客:算法系列——SPFA算法(贝尔曼-福特算法的队列优化形式)
附全部源码:
#北京 天津 郑州 济南 长沙 海南
# 0 1 2 3 4 5#模拟从文件中读入图的各个路径
a = """
0 1 500
0 2 100
1 2 900
1 3 300
2 3 400
2 4 500
3 4 1300
3 5 1400
4 5 1500
"""INF = float('inf')
N = 6weight = []def init():global weight#定义邻接矩阵 记录各城市之间的距离weight = [[INF if j!=i else 0 for j in range(N)] for i in range(N)]#解析数据b = [[int(i) for i in i.split(' ')] for i in a.split('\n') if i != '']for i in b:weight[i[0]][i[1]] = i[2]weight[i[1]][i[0]] = i[2]init()def bellman_ford(src, target):dist = [0 if i == src else INF for i in range(N)]#用于记录最后更新结点last_update = [src if i != INF else -1 for i in dist] #松弛n-1次,因为最短路径的深度最多是n-1,n为结点数目for i in range(N-1):change = False#分别遍历边的两个顶点,从而实现遍历所有边。for j in range(N):for k in range(N):if dist[j] > dist[k] + weight[j][k]:dist[j] = dist[k] + weight[j][k]#记录更新该结点的结点编号last_update[j] = k#标记更改状态change = True#如果本轮未作出更改,说明已完成if not change:break#判断负权回路 for i in range(N):for j in range(N):if dist[j] > dist[i] + weight[j][i]:raise ValueError("存在负权回路")#输出从起点到终点的路径结点tmp = targetpath = []while tmp != src:path.append(tmp)tmp = last_update[tmp]path.append(src)print("->".join([str(i) for i in reversed(path)]))return dist[target]
后记:看了两个晚上,第一个晚上看着看着放弃了,今天晚上又鼓起勇气开写,用了一晚上的时间,现在是次日凌晨1:27,终于完成了,希望能对看完本文的各位有所帮助,有所启发吧。我也在写的过程中不断学习,不断变得更秃、变得更强,晚安。
本文大部分内容来自百度百科,掺杂了一部分个人的理解和思考,感谢完成该词条的大佬们,写的很详细很易懂。 贝尔曼-福特算法
算法系列——贝尔曼福特算法(Bellman-Ford)相关推荐
- 算法:贝尔曼-福特算法
算法:贝尔曼-福特算法 1.简介 贝尔曼-福特算法(Bellman–Ford algorithm)是一个查找最短路径算法主要优点是支持负权重,但时间复杂度较高,还会有负权环的问题. 如果不需要权重应该 ...
- Python实现迪杰斯特拉算法和贝尔曼福特算法求解最短路径
文章目录 (一).题目 (二).导库 (三).绘制带权无向图 (四).获得最短路径 (四).实现最短路径高亮 (五).完整代码 (六).结果展示 关于Python数据分析在数学建模中的更多相关应用:P ...
- Bellman ford算法(贝尔曼·福特算法)
Bellman - ford算法是求含负权图的单源最短路径的一种算法,效率较低,代码难度较小.其原理为连续进行松弛,在每次松弛时把每条边都更新一下,若在n-1次松弛后还能更新,则说明图中有负环,因此无 ...
- 了解贝尔曼·福特算法
文章目录 为什么在现实生活中会有负权重的边? 为什么我们要留意负权重? 贝尔曼·福特算法如何工作 贝尔曼·福特伪码 Bellman Ford vs Dijkstra C示例 贝尔曼·福特算法的复杂度 ...
- C++实现bellman ford贝尔曼-福特算法(最短路径)(附完整源码)
C++实现bellman ford贝尔曼-福特算法 实现bellman ford贝尔曼-福特算法的完整源码(定义,实现,main函数测试) 实现bellman ford贝尔曼-福特算法的完整源码(定义 ...
- 算法-贝尔曼-福特算法
算法-贝尔曼-福特算法 注:该文是本博主记录学习之用,没有太多详细的讲解,敬请谅解! 一.简介 贝尔曼-福特算法(Bellman–Ford algorithm )用于计算出起点到各个节点的最短距离,支 ...
- JavaScript实现bellmanFord贝尔曼-福特算法(附完整源码)
JavaScript实现bellmanFord贝尔曼-福特算法 bellmanFord.js完整源代码 bellmanFord.js完整源代码 export default function bell ...
- 贝尔曼-福特算法(Bellman-Ford)最短路径问题
贝尔曼-福特算法(Bellman-Ford) 一.贝尔曼-福特算法(Bellman-Ford) 二.代码实现 一.贝尔曼-福特算法(Bellman-Ford) 贝尔曼-福特算法与迪科斯彻算法类似,都以 ...
- Bellman-Ford贝尔曼福特算法实现
作为一种单源最短路径算法,Bellman-Ford对于有向图和无向图都能适用,它还有一个Dijkstra算法无法具备的特点,那就是对含负权图的最短路径搜索. 每i轮对边的遍历之后,只要不存在负权回路, ...
最新文章
- linux oracle 远程exp_linux单独安装oracle客户端及exp/imp工具配置
- opencv打开相机实时采集与处理
- 是什么优化让 .NET Core 性能飙升?
- 腾讯游戏数据应用微服务实战
- Java基础复习-八大基本数据类型-内存模型-基本算法-网络编程
- WPF 实现水纹效果
- python批量合并csv_如何在Python中通过多个列合并两个CSV文件
- linux下Qt cannot find -lGL错误的解决方法
- lambda函数以及对 items.sort(key = lambda y:y[1], reverse = True) 的理解。
- HDU 5933 2016CCPC杭州 A: ArcSoft's Office Rearrangement
- XML PULL SAX到底有什么区别?
- 信息化为五万教学点带来“优质教师”
- html位置插入透明动画文字,鼠标放上去,图片上方动态显示半透明说明文字(源码)...
- 其它——简历编写、五险一金、补充一些就业相关的东西
- 【MATLAB】MATLAB 可视化之曲面图与网格图
- 【软件工程】瀑布模型的价值
- QT下使用QAxObject打开word文档,文档路径含有空格open出错的解决方法
- 迁移学习-域适应损失函数MMD-代码实现及验证
- 机械祭天法力无边:练习3.5:编写一段程序从标准输入中读入多个字符串并将它们连接在一起,输出连接成的大字符串。然后修改上述程序,用空格把输入的多个字符串分隔开来。
- Linux 根文件系统构建