本系列旨在用简单的人话讲解算法,尽可能避免晦涩的定义,读者可以短时间内理解算法原理及应用细节。我在努力!

本篇文章编程语言为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. 算法:贝尔曼-福特算法

    算法:贝尔曼-福特算法 1.简介 贝尔曼-福特算法(Bellman–Ford algorithm)是一个查找最短路径算法主要优点是支持负权重,但时间复杂度较高,还会有负权环的问题. 如果不需要权重应该 ...

  2. Python实现迪杰斯特拉算法和贝尔曼福特算法求解最短路径

    文章目录 (一).题目 (二).导库 (三).绘制带权无向图 (四).获得最短路径 (四).实现最短路径高亮 (五).完整代码 (六).结果展示 关于Python数据分析在数学建模中的更多相关应用:P ...

  3. Bellman ford算法(贝尔曼·福特算法)

    Bellman - ford算法是求含负权图的单源最短路径的一种算法,效率较低,代码难度较小.其原理为连续进行松弛,在每次松弛时把每条边都更新一下,若在n-1次松弛后还能更新,则说明图中有负环,因此无 ...

  4. 了解贝尔曼·福特算法

    文章目录 为什么在现实生活中会有负权重的边? 为什么我们要留意负权重? 贝尔曼·福特算法如何工作 贝尔曼·福特伪码 Bellman Ford vs Dijkstra C示例 贝尔曼·福特算法的复杂度 ...

  5. C++实现bellman ford贝尔曼-福特算法(最短路径)(附完整源码)

    C++实现bellman ford贝尔曼-福特算法 实现bellman ford贝尔曼-福特算法的完整源码(定义,实现,main函数测试) 实现bellman ford贝尔曼-福特算法的完整源码(定义 ...

  6. 算法-贝尔曼-福特算法

    算法-贝尔曼-福特算法 注:该文是本博主记录学习之用,没有太多详细的讲解,敬请谅解! 一.简介 贝尔曼-福特算法(Bellman–Ford algorithm )用于计算出起点到各个节点的最短距离,支 ...

  7. JavaScript实现bellmanFord贝尔曼-福特算法(附完整源码)

    JavaScript实现bellmanFord贝尔曼-福特算法 bellmanFord.js完整源代码 bellmanFord.js完整源代码 export default function bell ...

  8. 贝尔曼-福特算法(Bellman-Ford)最短路径问题

    贝尔曼-福特算法(Bellman-Ford) 一.贝尔曼-福特算法(Bellman-Ford) 二.代码实现 一.贝尔曼-福特算法(Bellman-Ford) 贝尔曼-福特算法与迪科斯彻算法类似,都以 ...

  9. Bellman-Ford贝尔曼福特算法实现

    作为一种单源最短路径算法,Bellman-Ford对于有向图和无向图都能适用,它还有一个Dijkstra算法无法具备的特点,那就是对含负权图的最短路径搜索. 每i轮对边的遍历之后,只要不存在负权回路, ...

最新文章

  1. linux oracle 远程exp_linux单独安装oracle客户端及exp/imp工具配置
  2. opencv打开相机实时采集与处理
  3. 是什么优化让 .NET Core 性能飙升?
  4. 腾讯游戏数据应用微服务实战
  5. Java基础复习-八大基本数据类型-内存模型-基本算法-网络编程
  6. WPF 实现水纹效果
  7. python批量合并csv_如何在Python中通过多个列合并两个CSV文件
  8. linux下Qt cannot find -lGL错误的解决方法
  9. lambda函数以及对 items.sort(key = lambda y:y[1], reverse = True) 的理解。
  10. HDU 5933 2016CCPC杭州 A: ArcSoft's Office Rearrangement
  11. XML PULL SAX到底有什么区别?
  12. 信息化为五万教学点带来“优质教师”
  13. html位置插入透明动画文字,鼠标放上去,图片上方动态显示半透明说明文字(源码)...
  14. 其它——简历编写、五险一金、补充一些就业相关的东西
  15. 【MATLAB】MATLAB 可视化之曲面图与网格图
  16. 【软件工程】瀑布模型的价值
  17. QT下使用QAxObject打开word文档,文档路径含有空格open出错的解决方法
  18. 迁移学习-域适应损失函数MMD-代码实现及验证
  19. 机械祭天法力无边:练习3.5:编写一段程序从标准输入中读入多个字符串并将它们连接在一起,输出连接成的大字符串。然后修改上述程序,用空格把输入的多个字符串分隔开来。
  20. Linux 根文件系统构建

热门文章

  1. C++调用ffmpeg批量合并bilibili缓存视频
  2. Visual SLAM 笔记——李群和李代数详解
  3. feologit:固定效应有序Logit模型
  4. Swing中Laber添加下划线
  5. Mantle Introduce
  6. 如何使用ABP开发一
  7. 网络上公开的华为一面、二面、三面、四面、五面过程的总结
  8. 十六进制与ascii码的互转(c语言),十六进制与ASCII码转换
  9. flink学习(五)DataStream API
  10. indiegogo众筹代理经验分享