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 算法非常相似。如果我们想找到最短路径,就可以在图上应用它。请注意,它可以处理负边权重。该算法的局限性在于图中不应存在负环(边权之和为负值的环)。考虑以下带环图。 ![]() 该算法的运行时复杂度为O(v*e),空间复杂度为O(v)。如果图具有负边权重,则应使用该算法。因此,Bellman-Ford 算法可应用于以下情况:
当所有弧都是负数时,该算法比 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 伪代码复杂度
让我们通过一个例子来理解这个算法。 Bellman-Ford 示例考虑以下有向图 (G)。 ![]() 边的顺序:(B, E), (D, B), (B, D), (A, B), (A, C), (D, C), (B, C), (E, D) 在上图中 (G),A 是所有其他顶点的起始顶点。 为了找到最短路径,首先,我们将源顶点 (A) 初始化为 0,将其他顶点初始化为无穷大 (∞)。之后,我们将从源节点遍历到每个顶点。在遍历过程中更新节点的值。我们创建了以下表格来更新距离。 ![]() ![]() 从源顶点 A,我们可以到达顶点 B 和 C。 ![]() 更新距离后,我们得到以下图。 ![]() 从顶点 B,我们可以到达顶点 C、D 和 E。计算从 B 到其他顶点的距离,我们得到 ![]() 更新距离后,我们得到以下图。 ![]() 从顶点 C 无法移动到任何顶点,所以我们将访问下一个顶点,即 D。 从顶点 D,我们可以到达顶点 B 和 C。计算从顶点 D 到其他顶点的距离。 移动 D -> B,我们注意到顶点 B 已经有了最小距离,所以这次我们不会更新距离。 ![]() 移动 D-> C,我们注意到顶点 C 已经有了最小距离,所以这次我们不会更新距离。 ![]() 更新距离后,我们得到以下图。 ![]() 从顶点 E,我们只能移动到顶点 D。计算从顶点 E 到 D 的距离。 ![]() 更新距离后,我们得到以下图。 ![]() 我们注意到值单调递减。 Java 中的 Bellman-Ford 实现BellmanFordExample1.java 输出 ![]() 结论找到具有非负边权重的图的最短路径是一个NP 难问题。要解决此类问题,不存在多项式时间算法。考虑一种情况,其中每条边都具有负边权重,我们可以应用 Bellman-Ford 算法。 可能存在从源可达的负权重环。在这种情况下,算法将终止。同样,如果我们想找到从源 (s) 到顶点 (v) 的最长简单路径,并且图中存在负环,则我们不能应用 Bellman-Ford 算法。 |
? 计算两个日期之间的时间差是编程中的常见任务。在 Java 中,可以使用内置的 Date 和 Calendar 类,或者更现代的 LocalDate 和 LocalTime 类来完成。在本节中,我们将探讨如何使用...
阅读 4 分钟
具有边框和标题的顶层窗口称为 Frame 类。作为默认布局管理器,它使用 BorderLayout。java.awt.Frame 组件是一个 Windows 图形系统组件,就像典型的 GUI 窗口一样,包含边框和标题栏。默认组件...
阅读 6 分钟
Apache Maven 是一个基于项目对象模型 (POM) 的项目管理工具。它对于依赖管理、项目构建和文档非常有用。要在我们的项目中添加任何依赖项,我们需要维护一个 pom.xml 文件,其中包含依赖项...
5 分钟阅读
Java 是一种流行的编程语言,用于开发各种应用程序。学习 Java 的最佳方法之一是练习编写程序。在线和图书馆都有许多资源可帮助您查找 Java 练习程序。在练习时...
阅读 10 分钟
native 关键字用于指示一个方法是在另一种语言(通常是 C 或 C++)中实现的。这些方法通常用于与硬件交互、操作系统级功能或提高特定任务的性能。请注意,native 关键字可以应用于……
阅读 3 分钟
在 Java 中,“finalisation”一词描述了对象在被垃圾回收之前所经历的清理过程。来自 java.lang.Object 类的 finalize() 函数使此过程更容易。子类应重写 finalize() 方法以释放资源...
5 分钟阅读
Java 中 next() 和 Line() 方法的区别 Java next() 方法 next() 方法在 Scanner 类中,用于从用户获取输入。为了使用此方法,需要创建一个 Scanner 对象。该方法可以...
5 分钟阅读
是当今世界上最流行的编程语言之一,广泛应用于从 Web 开发到移动应用程序开发的各种应用。Java 由 James Gosling 及其团队于 1990 年在 Sun Microsystems 开发。它因其简洁、易于……
阅读 4 分钟
在 C 和 C++ 编程语言中,从一个函数调用另一个函数的过程称为回调。函数的内存地址表示为函数指针。在 C 和 C++ 语言中,通过将函数指针传递给另一个函数来实现回调。与 C 不同...
阅读 4 分钟
java.time.format.DecimalStyle 类是 getDecimalSeparator() 方法。使用 DecimalStyle 类获取用于表示此 DecimalStyle 的 Locale 的小数分隔符的字符。该过程返回该区域设置的十进制分隔符的字符。语法:public char getDecimalSeparator() 参数:无参数...
阅读 2 分钟
我们请求您订阅我们的新闻通讯以获取最新更新。
我们提供所有技术(如 Java 教程、Android、Java 框架)的教程和面试问题
G-13, 2nd Floor, Sec-3, Noida, UP, 201301, India