博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

最短路径之弗洛伊德算法

Posted on 2020-08-21 13:26  池塘鱼  阅读(297)  评论(0)    收藏  举报

迪杰斯特拉算法VS弗洛伊德算法

迪杰斯特拉算法是求单源最短路径,通过选定的被访问顶点,求出从出发访问顶点到其他顶点的最短路径;弗洛伊德算法中每一个顶点都是出发访问点,所以需要将每一个顶点看做被访问顶点,求出从每一个顶点到其他顶点的最短路径。

弗洛伊德算法比迪杰斯特拉算法好实现,但是时间复杂度要更高。

思路

  1. 设置顶点Vi到顶点Vk的最短路径已知为Lik,顶点Vk到Vj的最短路径已知为Lkj,顶点Vi到Vj的路径为Lij,则Vi到Vj的最短路径为:min((Lik+Lkj),Lij),Vk的取值为图中所有顶点,则可获得Vi到Vj的最短路径;
  2. 至于Vi到Vk的最短路径Lik或者Vk到Vj的最短路径Lkj,是以同样的方式获得。

实现

package com.ex.greedy;

public class Floyd {
    static final int N = 10000;// 表示不可以连接
    public static void main(String[] args) {
        char[] vertex = { 'A', 'B', 'C', 'D', 'E' };
        //邻接矩阵
        int[][] matrix ={
                {0,4,N,2,N},
                {4,0,4,1,N},
                {N,4,0,1,3},
                {2,1,1,0,7},
                {N,N,3,7,0}
        };
        floyd(matrix,vertex);
    }

    public static void floyd(int[][] matrix, char[] vertex) {
        //准备
        int n=vertex.length;
        String path[][]=new String[n][n];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                path[i][j]=vertex[i]+"—>"+vertex[j];
            }
        }
        //循环
        for (int k = 0; k < vertex.length; k++) {//中间顶点
            for (int i = 0; i < vertex.length; i++) {//起始顶点
                for (int j = 0; j < vertex.length; j++) {//终点
                    //len记录从i出发,经过k,到达j的距离
                    int len=matrix[i][k]+matrix[k][j];
                    if (len<matrix[i][j]){
                        matrix[i][j]=len;
                        path[i][j]=path[i][k].substring(0,path[i][k].length()-1)+path[k][j];//A->D D->E 前面的终点是后面的起点,不重复记录
                    }
                }
            }
        }
        //输出
        for (int i = 0; i < vertex.length; i++) {
            for (int j = 0; j < vertex.length; j++) {
                System.out.printf("%-24s",matrix[i][j]+"(["+vertex[i]+":"+vertex[j]+"]  "+path[i][j]+")");
            }
            System.out.println();
        }

    }
}