您的位置:首页 > 文旅 > 旅游 > 最短路径算法:Floyd-Warshall算法

最短路径算法:Floyd-Warshall算法

2024/10/6 16:16:38 来源:https://blog.csdn.net/qq_40254606/article/details/140913259  浏览:    关键词:最短路径算法:Floyd-Warshall算法

引言

在图论中,Floyd-Warshall算法是一种用于计算任意两点之间最短路径的动态规划算法。它适用于加权有向图和无向图,可以处理带有负权重边的图,但要求图中不能有负权重环。本文将详细介绍Floyd-Warshall算法的定义、步骤及其实现。

Floyd-Warshall算法

定义

Floyd-Warshall算法是一种用于计算图中所有顶点对之间最短路径的算法。该算法利用动态规划的思想,通过不断更新顶点对之间的最短路径,最终得到所有顶点对的最短路径矩阵。

算法步骤

  1. 初始化:创建一个距离矩阵dist,其中dist[i][j]表示顶点i到顶点j的初始距离。如果i和j之间有边,则dist[i][j]为边的权重;如果i和j之间没有边且i≠j,则dist[i][j]为正无穷大;如果i=j,则dist[i][j]为0。
  2. 更新距离矩阵:对于每一对顶点(i, j),通过中间顶点k更新其最短路径。具体来说,如果dist[i][j] > dist[i][k] + dist[k][j],则更新dist[i][j] = dist[i][k] + dist[k][j]。
  3. 重复更新:重复上述步骤,直到所有顶点对之间的最短路径都被计算出来。

示例

假设我们有一个带权有向图,顶点集合为 ({A, B, C, D}),边和权重集合为 ({(A, B, 3), (A, C, 8), (A, D, -4), (B, D, 1), (B, C, -2), (C, A, 4), (D, C, 7), (D, B, -5)})。

3
8
-4
1
-2
4
7
-5
A
B
C
D

Floyd-Warshall算法图解

  1. 初始化距离矩阵
  A   B   C   D
A 0   3   8  -4
B ∞   0  -2   1
C 4  ∞   0  ∞
D ∞  -5   7   0
  1. 通过顶点A更新距离矩阵
  A   B   C   D
A 0   3   8  -4
B 7   0  -2   1
C 4  ∞   0  ∞
D 3  -5   7   0
  1. 通过顶点B更新距离矩阵
  A   B   C   D
A 0   3   1  -4
B 5   0  -2   1
C 4  7   0  ∞
D 3  -5   2   0
  1. 通过顶点C更新距离矩阵
  A   B   C   D
A 0   3   1  -4
B 5   0  -2   1
C 4  7   0  ∞
D 3  -5   2   0
  1. 通过顶点D更新距离矩阵
  A   B   C   D
A 0  -1   1  -4
B 5   0  -2   1
C 4  -1   0  -3
D 3  -5   2   0

Floyd-Warshall算法实现

下面是用Java实现Floyd-Warshall算法的代码示例:

import java.util.Arrays;public class FloydWarshallAlgorithm {private static final int INF = 99999; // 表示无穷大的值// 计算任意两点之间的最短路径public void floydWarshall(int[][] graph) {int vertices = graph.length;int[][] dist = new int[vertices][vertices];// 初始化距离矩阵for (int i = 0; i < vertices; i++) {for (int j = 0; j < vertices; j++) {dist[i][j] = graph[i][j];}}// 更新距离矩阵for (int k = 0; k < vertices; k++) {for (int i = 0; i < vertices; i++) {for (int j = 0; j < vertices; j++) {if (dist[i][k] != INF && dist[k][j] != INF && dist[i][k] + dist[k][j] < dist[i][j]) {dist[i][j] = dist[i][k] + dist[k][j];}}}}printSolution(dist);}// 打印最短路径矩阵private void printSolution(int[][] dist) {int vertices = dist.length;System.out.println("顶点对之间的最短路径矩阵:");for (int i = 0; i < vertices; i++) {for (int j = 0; j < vertices; j++) {if (dist[i][j] == INF) {System.out.print("INF ");} else {System.out.print(dist[i][j] + "   ");}}System.out.println();}}public static void main(String[] args) {int[][] graph = {{0, 3, 8, -4},{INF, 0, -2, 1},{4, INF, 0, INF},{INF, -5, 7, 0}};FloydWarshallAlgorithm floydWarshall = new FloydWarshallAlgorithm();floydWarshall.floydWarshall(graph);}
}

代码注释

  1. 常量定义

    private static final int INF = 99999; // 表示无穷大的值
    

    INF 表示无穷大,用于表示顶点之间没有直接连接。

  2. Floyd-Warshall算法

    public void floydWarshall(int[][] graph) {int vertices = graph.length;int[][] dist = new int[vertices][vertices];// 初始化距离矩阵for (int i = 0; i < vertices; i++) {for (int j = 0; j < vertices; j++) {dist[i][j] = graph[i][j];}}// 更新距离矩阵for (int k = 0; k < vertices; k++) {for (int i = 0; i < vertices; i++) {for (int j = 0; j < vertices; j++) {if (dist[i][k] != INF && dist[k][j] != INF && dist[i][k] + dist[k][j] < dist[i][j]) {dist[i][j] = dist[i][k] + dist[k][j];}}}}printSolution(dist);
    }
    

    floydWarshall 方法实现了Floyd-Warshall算法,计算任意两点之间的最短路径。

  3. 打印最短路径矩阵

    private void printSolution(int[][] dist) {int vertices = dist.length;System.out.println("顶点对之间的最短路径矩阵:");for (int i = 0; i < vertices; i++) {for (int j = 0; j < vertices; j++) {if (dist[i][j] == INF) {System.out.print("INF ");} else {System.out.print(dist[i][j] + "   ");}}System.out.println();}
    }
    

    printSolution 方法用于打印最短路径矩阵。

结论

通过上述讲解和实例代码,我们详细展示了Floyd-Warshall算法的定义、步骤及其实现。Floyd-Warshall算法是一种重要的最短路径算法,适用于计算任意两点之间的最短路径。希望这篇博客对您有所帮助!


如果您觉得这篇文章对您有帮助,请关注我的CSDN博客,点赞并收藏这篇文章,您的支持是我持续创作的动力!


关键内容总结

  • Floyd-Warshall算法的定义
  • Floyd-Warshall算法的步骤
  • Floyd-Warshall算法的实现及其

代码注释


推荐阅读:深入探索设计模式专栏,详细讲解各种设计模式的应用和优化。点击查看:深入探索设计模式。


特别推荐:设计模式实战专栏,深入解析设计模式的实际应用,提升您的编程技巧。点击查看:设计模式实战。

如有任何疑问或建议,欢迎在评论区留言讨论。谢谢阅读!

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com