zoukankan      html  css  js  c++  java
  • 最短路径算法:弗洛伊德(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
  • 相关阅读:
    14-快速排序
    linux上挂在windows的共享文件系统,大小写不敏感
    【mount】linux挂共享盘
    监控windows服务或者进程
    自定义时间间隔
    示例
    filebeat
    kafka
    文档碎片
    简单DOM操作
  • 原文地址:https://www.cnblogs.com/magic-sea/p/11944756.html
Copyright © 2011-2022 走看看