贝尔曼-福特算法

  • 什么是贝尔曼-福特算法
  • 操作步骤
  • 负权边
  • 时间复杂度

什么是贝尔曼-福特算法

贝尔曼-福特(Bellman-Ford)算法用于在加权图中求解最短路径问题。它通过对所有边反复进行松弛操作,逐步逼近最短路径。

操作步骤

以 A 为起点、G 为终点为例:

B --1-- E
|      |
9      5
|      |
A --6-- D --3-- G
|      |      |
2      2      4
|      |
C --9-- F

第 1 步:初始化——起点 A 的权重为 0,其他顶点为无穷大(∞)

A=0  B=∞  C=∞  D=∞  E=∞  F=∞  G=∞

第 2 步:遍历所有边,对每条边计算「顶点权重 + 边权重」,如果比目标顶点当前权重小就更新

选边 A-B: A 的权重 0 + 边权 9 = 9 < ∞ → 更新 B=9
选边 A-C: 0 + 2 = 2 < ∞ → 更新 C=2
选边 A-D: 0 + 6 = 6 < ∞ → 更新 D=6
选边 C-B: 2 + 9 = 11 > 9 → 不更新
选边 B-D: 9 + ... 
...(对所有边执行一轮)

第 3 步:重复第 2 步,直到所有顶点的权重不再更新

第1轮结束: A=0  B=8  C=2  D=4  E=9  F=10  G=14
第2轮结束: A=0  B=7  C=2  D=4  E=8  F=10  G=14
第3轮结束: 所有顶点都不再更新 → 结束

最终最短路径:A → C → D → F → G,权重为 14。

负权边

贝尔曼-福特算法的最大优势是能处理负权边

如果图中有一条负权边:
  A --4--> B --(-3)--> C

从 A 到 C: 4 + (-3) = 1,比直接 A → C 更短

但如果一个闭环的权重总和为负数,不断遍历这个闭环就能让路径权重无限减小,此时不存在最短路径。贝尔曼-福特算法可以通过检测「n 轮更新后是否还能继续更新」来判断这种情况。

时间复杂度

项目 时间复杂度 说明
每轮更新 O(m) 遍历所有 m 条边
总轮数 n 最多 n 轮(n 为顶点数)
总计 O(nm)

与狄克斯特拉算法的对比

对比项 贝尔曼-福特 狄克斯特拉
负权边 支持 不支持
时间复杂度 O(nm) O(n²)
适合场景 有负权边的图 无负权边的图

小结

  • 贝尔曼-福特通过对所有边反复松弛来求最短路径
  • 支持负权边(最大优势),能检测负权环
  • 时间复杂度 O(nm),比狄克斯特拉慢
  • 存在负权边时用贝尔曼-福特,否则用更快的狄克斯特拉