算法->Floyd算法入门

92 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第22天,点击查看活动详情

Floyd算法介绍

Floyd算法是经典的动态规划算法,基本思想是递推产生一个矩阵序列A1,A2,.....,Ak,...,An(图有n个节点),Ak=(ak(i,j))nxn。其中矩阵Ak第i行第j列表示从顶点vi到顶点vj的路径上经过的顶点序号不大于k的最短路径长度。

算法的原理

算法实现无外乎就是三个循环嵌套,i,j的循环是任意两个点,而k则是两个点之间所经过的第三个点,我们就是在循环之中不断比较从i到j的距离与从i到k距离加上从k到j距离的大小,如果经过这个点,路径变短了,我们就接受这个点,认为可以经过这个点;否则就不经过这个点,就是从i到j最短。

算法实现

image.png

  1. 先生成图的邻接距阵与路径距阵
  2. 用d[i,j]表示i点到j点的最短距离,但i到j可能会经过K个顶点才能找到最短路径: d[i][j]=d[i][k]+d[k][j],其中的k可能为多个点
  3. 遍历全部顶点,如果出现d[i][j]>d[i][k]+d[k][j],我们就用短的路径替换长的路径,如图中v1->v2直接走为4,用v1->v0->v2==3
  4. 为了找到全部结点对之间的最短路径,可以在路径计算过程中,取数组p[i][j]=p[i][k]用于记录每次的替换过程;

代码实现

    public static final int I = 100;
    //邻接距阵
    public static int[][] d = new int[][]{
            {0, 2, 1, 5},
            {2, 0, 4, I},
            {1, 4, 0, 3},
            {5, I, 3, 0}
    };
    public static int[][] p=new int[][]{
            {0,1,2,3},
            {0,1,2,3},
            {0,1,2,3},
            {0,1,2,3}
    };
    public static void floyd(){
        for (int k = 0; k < d.length; k++) {
            for(int i=0;i<d.length;i++){
                for (int j = 0; j < d.length; j++) {
                    if(d[i][j]>d[i][k]+d[k][j]){
                        d[i][j]=d[i][k]+d[k][j];
                        //记录下路径
                        p[i][j]=p[i][k];
                    }
                }
            }
        }
    }