最短路径算法:弗洛伊德(Floyd-Warshall)算法

一、算法介绍

  Floyd-Warshall算法(英语:Floyd-Warshall algorithm),中文亦称弗洛伊德算法,是解决任意两点间的最短路径的一种算法,可以正确处理有向图或负权(但不可存在负权回路)的最短路径问题,同时也被用于计算有向图的传递闭包。Floyd-Warshall算法的时间复杂度为 O(N3),空间复杂度为 O(N2),因时间复杂度比较高,不适合计算大量数据。

二、算法原理

Floyd-Warshall算法的原理是动态规划,Floyd算法适用于APSP(All Pairs Shortest Paths,多源最短路径)。

 Di,j,k 为从 i 到 j 的只以 (1..k) 集合中的节点为中间节点的最短路径的长度。

  1. 若最短路径经过点 k,则 Di,j,k = Di,k,k-1 + Dk,j,k-1
  2. 若最短路径不经过点 k,则 Di,j,k =Di,j,k-1

因此,Di,j,k = min (Di,j,k-1, Di,k,k-1 + Dk,j,k-1)。

1         for (k = 0; k < V; k++) {
2             for (i = 0; i < V; i++) {
3                 for (j = 0; j < V; j++) {
4                     if (dist[i][j] > dist[i][k] + dist[k][j]) {
5                         dist[i][j] = dist[i][k] + dist[k][j];
6                     }
7                 }
8             }
9         }

输入矩阵:

1     int[][] graph = {
2                 {0,   5,  INF, 10},
3                 {INF, 0,   3, INF},
4                 {INF, INF, 0,   1},
5                 {INF, INF, INF, 0}
6     };

输出结果:

1   Shortest distance matrix : 
2       0      5      8      9
3     INF      0      3      4
4     INF    INF      0      1
5     INF    INF    INF      0

  初始化与输入图矩阵相同的求解矩阵。然后,我们通过将所有顶点视为中间顶点来更新解矩阵。这个思想是一个接一个地选取所有顶点并更新所有最短路径,其中包括所选取的顶点作为最短路径中的中间顶点。

源代码:

 1 package algorithm.shortestpath;
 2 
 3 public class AllPairShortestPath {
 4     final static int INF = 99999, V = 4;
 5 
 6     public void floydWarshall(int[][] graph) {
 7         int[][] dist = new int[V][V];
 8         int i, j ,k;
 9         for (i = 0; i < V; i++) {
10             for (j = 0; j < V; j++) {
11                 dist[i][j] = graph[i][j];
12             }
13         }
14         for (k = 0; k < V; k++) {
15             for (i = 0; i < V; i++) {
16                 for (j = 0; j < V; j++) {
17                     if (dist[i][j] > dist[i][k] + dist[k][j]) {
18                         dist[i][j] = dist[i][k] + dist[k][j];
19                     }
20                 }
21             }
22         }
23         printSoultion(dist);
24     }
25 
26     private void printSoultion(int[][] dist) {
27         System.out.println("The following matrix shows the shortest "+
28                 "distances between every pair of vertices");
29         for (int i = 0; i < V; ++i) {
30             for (int j = 0; j < V; ++j) {
31                 if (dist[i][j] == INF) {
32                     System.out.print("INF ");
33                 } else {
34                     System.out.print(dist[i][j] + "   ");
35                 }
36             }
37             System.out.println();
38         }
39     }
40 
41     public static void main(String[] args) {
42         /* 输入带权重矩阵
43                10
44          (0)------->(3)
45           |         /|\
46         5 |          |
47           |          | 1
48          \|/         |
49          (1)------->(2)
50                3           */
51         int[][] graph = {
52                 {0,   5,  INF, 10},
53                 {INF, 0,   3, INF},
54                 {INF, INF, 0,   1},
55                 {INF, INF, INF, 0}
56         };
57 
58         AllPairShortestPath a = new AllPairShortestPath();
59 
60         a.floydWarshall(graph);
61     }
62 }
View Code
posted @ 2019-11-27 19:19  賣贾笔的小男孩  阅读(3403)  评论(0编辑  收藏  举报