常用的十种算法--弗洛伊德算法

1.弗洛伊德算法介绍:

        弗洛伊德算法选取某个节点k作为i到j需要经过的中间节点,通过比较d(i,k)+d(k,j)和现有d(i,j)的大小,将较小值更新为路径长度,对k节点的选取进行遍历,以得到在经过所有节点时i到j的最短路径长度,通过不断加入中间点的方式更新最短路径。同时在path数组中存储i到j所经过的中间节点k,用于最后递归调用输出路径结果。

2.示意图:

3.应用场景:

4.代码实现: 

package algorithm;

/**
 * @author WuChenGuang
 */
public class FloydAlgorithm {

    public static int MaxValue = 100000;

    /**
     * 中间节点存放的数组
     */
    public static int[][] path;

    public static void main(String[] args) {
        // 顶点数
        int vertex = 7;
        // 边数
        int edge = 10;

        int[][] matrix = new int[vertex][vertex];

        for (int i = 0; i < vertex; i++) {
            for (int j = 0; j < vertex; j++) {
                matrix[i][j] = MaxValue;
            }
        }

        path = new int[matrix.length][matrix.length];

        matrix[0][1] = 6;
        matrix[1][2] = 5;
        matrix[0][3] = 2;
        matrix[3][1] = 7;
        matrix[3][4] = 5;
        matrix[1][2] = 5;
        matrix[1][5] = 3;
        matrix[5][2] = 3;
        matrix[5][4] = 2;
        matrix[4][6] = 1;
        floyd(matrix);
    }

    public static void floyd(int[][] matrix) {
        // 防止int类型数组中默认值是0,因为顶点也存在0的数据
        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix.length; j++) {
                path[i][j] = -1;
            }
        }

        /*
          计算 i通过中间顶点k 到达j 的路径
          i --k--j
          0--0--0
          0--0--1
          0--0--2
          ...
          0--0--6

          1--0--0
          1--0--1
          1--0--2
          6--0--6

          0--1--0
         */
        for (int k = 0; k < matrix.length; k++) {
            for (int i = 0; i < matrix.length; i++) {
                for (int j = 0; j < matrix.length; j++) {
                    if (matrix[i][k] + matrix[k][j] < matrix[i][j]) {
                        matrix[i][j] = matrix[i][k] + matrix[k][j];
                        path[i][j] = k;
                    }
                }
            }
        }

        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix.length; j++) {
                if (i != j) {
                    if (matrix[i][j] == MaxValue) {
                        System.out.println(i + "到" + j + "不可以直达");
                    } else {
                        System.out.print(i + "到" + j + "最短路径:" + matrix[i][j]);
                        System.out.print("最短路径:" + i + "----->");
                        searchPath(i, j);
                        System.out.println(j);
                    }
                }
            }
        }
    }

    public static void searchPath(int i, int j) {
        int m = path[i][j];
        if (m == -1) {
            return;
        }
        searchPath(i, m);
        System.out.println(m + "--->");
        searchPath(m, j);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ll520.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值