Java Bellman-Ford 算法

2025 年 5 月 12 日 | 阅读 6 分钟

动态规划中,有许多算法可以找到图中的最短路径。其中一些是Dijkstra 算法、BFS、DFS、Floyd、所有对最短路径问题双向算法。最常用的算法是Dijkstra 算法。该算法的局限性在于,如果图具有负边权重,则无法应用。另一个区别是 Dijkstra 算法仅查看顶点的直接邻居,而 Bellman-Ford 在每次迭代中都遍历所有边。

为了克服这个问题,可以使用Bellman-Ford 算法。它可以处理负边权重。在本节中,我们将通过示例理解 Bellman-Ford 算法,并在 Java 程序中实现 Bellman ford 算法。

Bellman-Ford 算法

它是一种单源最短路径(最小权重)算法,与 Dijkstra 算法非常相似。如果我们想找到最短路径,就可以在图上应用它。请注意,它可以处理负边权重。该算法的局限性在于图中不应存在负环(边权之和为负值的环)。考虑以下带环图。

Bellman-Ford Algorithm Java

该算法的运行时复杂度为O(v*e),空间复杂度为O(v)。如果图具有负边权重,则应使用该算法。因此,Bellman-Ford 算法可应用于以下情况:

  • 负边权重
  • 正边权重 > 1
  • 无向环

当所有弧都是负数时,该算法比 Dijkstra 算法慢。

Bellman-Ford 算法的工作原理

Bellman-Ford 算法的工作原理与 Dijkstra 算法相同。唯一的区别是它不使用优先队列。它会重复遍历所有边,并像 Dijkstra 算法一样更新起点上的距离。

如果图G=(V, E)包含负权重环,则某些最短路径可能不存在。Bellman-Ford 算法找到从源s ϵ V到所有v ϵ V的所有最短路径长度,或确定存在负权重环。

给定一个有权重的有向图 G(V, E) 和源 (s) 以及权重函数w: E -> R,当且仅当图中不存在从源可达的负权重环时,该算法返回布尔值TRUE。该算法会产生最短路径及其权重。如果存在这样的环,则算法会指示无解

算法

Bellman Ford 伪代码

复杂度

时间复杂度最佳情况O(E)
平均情况O(VE)
最坏情况O(VE)
空间复杂度O(V)

让我们通过一个例子来理解这个算法。

Bellman-Ford 示例

考虑以下有向图 (G)。

Bellman-Ford Algorithm Java

边的顺序:(B, E), (D, B), (B, D), (A, B), (A, C), (D, C), (B, C), (E, D)

在上图中 (G),A 是所有其他顶点的起始顶点。

为了找到最短路径,首先,我们将源顶点 (A) 初始化为 0,将其他顶点初始化为无穷大 ()。之后,我们将从源节点遍历到每个顶点。在遍历过程中更新节点的值。我们创建了以下表格来更新距离。

Bellman-Ford Algorithm Java
Bellman-Ford Algorithm Java

从源顶点 A,我们可以到达顶点 B 和 C。

Bellman-Ford Algorithm Java

更新距离后,我们得到以下图。

Bellman-Ford Algorithm Java

从顶点 B,我们可以到达顶点 C、D 和 E。计算从 B 到其他顶点的距离,我们得到

Bellman-Ford Algorithm Java

更新距离后,我们得到以下图。

Bellman-Ford Algorithm Java

从顶点 C 无法移动到任何顶点,所以我们将访问下一个顶点,即 D。

从顶点 D,我们可以到达顶点 B 和 C。计算从顶点 D 到其他顶点的距离。

移动 D -> B,我们注意到顶点 B 已经有了最小距离,所以这次我们不会更新距离。

Bellman-Ford Algorithm Java

移动 D-> C,我们注意到顶点 C 已经有了最小距离,所以这次我们不会更新距离。

Bellman-Ford Algorithm Java

更新距离后,我们得到以下图。

Bellman-Ford Algorithm Java

从顶点 E,我们只能移动到顶点 D。计算从顶点 E 到 D 的距离。

Bellman-Ford Algorithm Java

更新距离后,我们得到以下图。

Bellman-Ford Algorithm Java

我们注意到值单调递减。

Java 中的 Bellman-Ford 实现

BellmanFordExample1.java

输出

Bellman-Ford Algorithm Java

结论

找到具有非负边权重的图的最短路径是一个NP 难问题。要解决此类问题,不存在多项式时间算法。考虑一种情况,其中每条边都具有负边权重,我们可以应用 Bellman-Ford 算法。

可能存在从源可达的负权重环。在这种情况下,算法将终止。同样,如果我们想找到从源 (s) 到顶点 (v) 的最长简单路径,并且图中存在负环,则我们不能应用 Bellman-Ford 算法。