最短路径算法-java实现

弗洛伊德算法(Floyd):

先初始化,两个矩阵,一个是图的邻接矩阵D,一个是路径矩阵P。

 最短路径算法-java实现_第1张图片

之后,沿着对角线,更新矩阵D和P:

例如:D[0][2]更新为锁定的行列下的,D[0][1]+D[1][2]=4

所以,P[0][2],从0点到达了2点时,中途还经过了1点,所以P[0][2]

最短路径算法-java实现_第2张图片

最后计算完,根据P矩阵,复原路径:

例如:P[0][8]=1,说明经过了第一个节点v1,然后再算P[1][8]=2,说明经过了第二个节点v2,以此类推...

public class FloydInGraph {

    private static int INF = Integer.MAX_VALUE;
    private int[][] dist;
    //顶点i 到 j的最短路径长度,初值是i到j的边的权重
    private int[][] path;
    private List result = new ArrayList<>();

    public static void main(String[] args) {
        //创建一个5x5的邻接矩阵来存储图
        FloydInGraph graph = new FloydInGraph(5);
        int[][] matrix = {
                {INF, 30, INF, 10, 50},
                {INF, INF, 60, INF, INF},
                {INF, INF, INF, INF, INF},
                {INF, INF, INF, INF, 30},
                {50, INF, 40, INF, INF},
        };
        int begin = 0;
        int end = 4;
        graph.findCheapestPath(begin, end, matrix);
        List list = graph.result;
        System.out.println(begin + " to " + end + ",the cheapest path is:");
        System.out.println(list.toString());
        System.out.println(graph.dist[begin][end]);
    }

    public void findCheapestPath(int begin, int end, int[][] matrix) {
        //求出matrix的最短路径
        floyd(matrix);
        result.add(begin);
        findPath(begin, end);
        result.add(end);
    }

    public void findPath(int i, int j) {
        // 找到路由节点
        int k = path[i][j];
        if (k == -1)
            return;
        // 从i到路由节点进行递归寻找中间节点
        findPath(i, k);
        result.add(k);
        // 从j到路由节点进行递归寻找中间节点
        findPath(k, j);
    }

    public void floyd(int[][] matrix) {
        int size = matrix.length;
        for (int i = 0; i < size; i++) {
            for (int j = 0; j < size; j++) {
                path[i][j] = -1;
                dist[i][j] = matrix[i][j];
            }
        }
        for (int k = 0; k < size; k++) {
            for (int i = 0; i < size; i++) {
                for (int j = 0; j < size; j++) {
                    if (dist[i][k] != INF && dist[k][j] != INF && dist[i][k] + dist[k][j] < dist[i][j]) {
                        // 更新i和j两点间的距离
                        dist[i][j] = dist[i][k] + dist[k][j];
                        // 记录从i点到j点序列的,中间第一个节点k
                        path[i][j] = k;
                    }
                }
            }
        }
    }

    public FloydInGraph(int size) {
        this.path = new int[size][size];
        this.dist = new int[size][size];
    }
}

 

你可能感兴趣的:(Java学习笔记)