Floyd-Warshall 算法2025年3月17日 | 阅读 12 分钟 Floyd-Warshall 算法是一种动态规划算法,用于发现加权图中的最短路径,包括负权重循环。该算法通过计算图中每对顶点之间的最短路径,并使用中间顶点矩阵来跟踪迄今为止已知的最佳路径。 但在我们开始之前,让我们简要了解一下什么是动态规划。 理解动态规划动态规划是一种在计算机科学和数学中使用的技术,通过将复杂问题分解为较小的子问题并尽可能简单地解决每个子问题来解决复杂问题。它是一种优化技术,可以通过利用子问题的解决方案来找到解决问题的最佳方法。 动态规划背后的关键思想是将子问题的解决方案存储在内存中,以便在解决更大的问题时可以重复使用它们。这降低了规则集的时间和空间复杂性,并允许它解决比暴力方法大得多和更复杂的问题。 动态规划有两种重要类型
记忆化涉及将每个子问题的结果存储在缓存中,以便以后可以重复使用。表格化涉及以自下而上的方式构建子问题解决方案表,从最小的子问题开始,然后逐步扩展到更大的子问题。动态规划广泛应用于优化问题、计算几何、设备学习和自然语言处理等领域。 动态规划可以解决的一些著名问题包括斐波那契数列、背包问题和最短路径问题。 Floyd-Warshall 算法的历史Floyd-Warshall 规则集由 Robert Floyd 和 Stephen Warshall 于 1962 年独立开发。Robert Floyd 是 IBM Thomas J. Watson 研究中心的数学家和计算机科学家,而 Stephen Warshall 是加利福尼亚大学伯克利分校的计算机科学家。该算法最初是用于运筹学领域,用于解决具有正或负边权重的有向图中的所有对最短路径问题。该问题在运筹学中引起了极大的兴趣,因为它在交通、通信和物流方面有许多应用。 Floyd 于 1962 年在一份题为“算法 97:最短路径”的技术报告中首次介绍了该规则集。Warshall 很快独立发现了该规则集,并在他自己的技术报告“布尔矩阵定理”中发表了它。此后,该算法已成为计算机科学的基石,并广泛应用于研究和行业的许多领域。它能够有效地找到图中所有顶点对之间的最短路径,包括具有负边权重的路径,这使其成为解决各种优化问题的宝贵工具。 Floyd-Warshall 算法的工作原理规则集的工作原理如下
示例Floyd-Warshall 是一种用于查找加权图中所有顶点对之间最短路径的算法。它通过维护一个包含每对顶点之间距离的矩阵,并迭代更新此矩阵直到找到最短路径。 让我们看一个例子来解释 Floyd-Warshall 算法的工作原理 考虑以下加权图 ![]() 图: 加权图 在此图中,顶点由字母(A、B、C、D)表示,边缘上的数字表示这些边缘的权重。 为了将 Floyd-Warshall 算法应用于此图,我们首先初始化每对顶点之间的距离矩阵。如果两个顶点直接通过边连接,则它们的距离是该边的负载。如果顶点之间没有直接边,则它们的距离是无限的。 ![]() 在规则集的第一遍迭代中,我们考虑使用顶点 1 (A) 作为所有顶点对之间路径中的中间顶点的可能性。如果从顶点 1 到顶点 2 的空间加上从顶点 2 到顶点 3 的空间小于从顶点 1 到顶点 3 的当前距离,那么我们用这个新距离更新矩阵。我们对每对可能的顶点都这样做。 ![]() 在第二遍迭代中,我们再次考虑使用顶点 2 (B) 作为所有顶点对之间路径中的中间顶点的可能性。我们像以前一样更新矩阵。 ![]() 在第三遍迭代中,我们考虑使用顶点 3 (C) 作为所有顶点对之间路径中的中间顶点的可能性。 ![]() 最后,在第四次也是最后一次迭代中,我们考虑使用顶点 4 (D) 作为所有顶点对之间路径中的中间顶点的可能性。 ![]() 第四次迭代后,我们得到了图中每对顶点之间的最短路径。例如,从顶点 A 到顶点 D 的最短路径是 4,这是矩阵中 A 行 D 列的值。 Floyd-Warshall 算法在不同编程语言中的实现我们现在将看到 Floyd-Warshall 算法在 C、C++、Java 和 Python 等不同编程语言中的实现。 C 语言实现代码以下是 C 语言编写的 Floyd-Warshall 算法实现程序代码。 程序代码 输出 Shortest distances between all pairs of vertices: 0 5 8 9 INF 0 3 4 INF INF 0 1 INF INF INF 0 C++ 中的代码实现以下是 C++ 编写的 Floyd-Warshall 算法实现程序代码。 程序代码 输出 Shortest distances between all pairs of vertices: 0 5 8 9 INF 0 3 4 INF INF 0 1 INF INF INF 0 Java 代码实现以下是 Java 编写的 Floyd-Warshall 算法实现程序代码。 程序代码 输出 0 3 3 5 2 0 2 4 3 1 0 5 5 3 2 0 Python中的代码实现以下是 Python 编写的 Floyd-Warshall 算法实现程序代码。 程序代码 输出 [0, 3, 7, 5] [2, 0, 6, 4] [3, 1, 0, 5] [5, 3, 2, 0] 理解 Floyd-Warshall 算法的时间和空间复杂度时间复杂度 - 该算法的总体时间复杂度为 O(N^3),其中 N 是图中顶点的数量。它适用于具有糟糕权重循环的密集图,因为它可以处理它们而不会陷入无限循环。但是,对于稀疏图,Dijkstra 算法或 Bellman-Ford 算法可能更有效。 当我们谈论时间复杂度时,让我们完成关于为什么 Bellman-Ford 或 Dijkstra 最短路径算法不适合解决包括所有节点对的最短路径问题的未完成讨论。 Bellman-Ford 和 Dijkstra 最短路径算法只计算从一个节点到所有其他节点的最短路径,它们的上限,其中 n 和 m 分别是节点和边的数量,分别为 O(nm) 和 O(n+mlogn)。 此外,Dijkstra 最短路径算法对于负加权边无效。 如果将 Bellman-Ford 算法扩展到包含所有节点,则时间复杂度变为 n*O(nm) = O(n^2*m)。 Floyd Warshall 算法只考虑节点数量,因此有向网络的最大边数可以高达 n*(n-1),这意味着总复杂度可以高达 O(n^4)。 因此,Floyd-Warshall 算法是更好的选择! 空间复杂度 - 该算法需要一个二维数组,通常称为“距离矩阵”,用于存储图中每对顶点之间的最短路径距离。空间矩阵的大小由图中顶点的数量决定,其空间复杂度为 O(V^2),其中 V 是图中顶点的范围。 除了空间矩阵,该算法还需要一个二维数组来跟踪任意两个顶点之间最短路径上的中间顶点。这个数组通常被称为“路径矩阵”;它的空间复杂度也是 O(V^2)。 因此,Floyd-Warshall 规则集的总体空间复杂度为 O(V^2),这意味着算法所需的内存量随图中顶点的数量呈二次增长。对于具有许多顶点的大型图来说,这可能是一个问题,因为该算法可以快速变得内存密集,并且可能无法在内存有限的机器上运行。 Floyd-Warshall 算法的一些优点和缺点现在让我们讨论一下使用 Floyd-Warshall 算法的一些优点和缺点 Floyd-Warshall 算法的优点包括
Floyd-Warshall 规则集的缺点包括
Floyd Warshall 算法的应用Floyd-Warshall 算法是一种动态规划算法,用于查找加权图中所有顶点对之间的最短路径。以下是 Floyd-Warshall 算法的一些程序
这些只是 Floyd-Warshall 算法的众多应用中的一小部分。它是一种功能强大的算法,可以在广泛的领域中应用于解决大量问题。 下一个主题算法的特性 |
我们请求您订阅我们的新闻通讯以获取最新更新。