Floyd算法计算最短距离

 思路理解:

虽然K从0开始到n-1,代表的分别是以A,B,C...作为中间节点去计算最短距离

我们以EF两点距离来看,再k=0时,我们选择A点作为中间节点,考虑了d(EF)和d(EA)+d(AF)的大小,并且取较小值更新d(EF)

在k=1时,选择B点作为中间节点,考虑了d(EF)和d(EB)+d(BF)的大小,这个地方要注意的是在第一轮中d(EB)和d(BF)必然已经被比较过一次(EA+AB和BA+AF),

所以,经过第二轮比较,d(EF)已经是所有以A和B作为中间节点的组合中的最小值,这个组合不仅仅是d(EAF)和d(EBF),还包含了d(EABF)和d(EBAF)

那么可以退出当k等于n-1的时候,EF已经尝试了将0~n的节点的所有组合作为中间节点,那么它的长度必然是这些组合中最短的.

import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Table;

import java.util.Arrays;

public class App {

    //正无穷
    public static double infinity = Double.POSITIVE_INFINITY;

    /**
     * 计算所有节点最短路径的Floyd算法
     * 记住k一定再最外层循环!
     *
     * @param graph 图的距离矩阵
     */
    public static double[][] floyd(double[][] graph) {
        int N = graph.length;
        double[][] distance = new double[N][N];

        //权重矩阵复制一份给距离矩阵
        for (int i = 0; i < N; i++) {
            System.arraycopy(graph[i], 0, distance[i], 0, graph[i].length);
        }

        for (int k = 0; k < N; k++) {
            for (int i = 0; i < N; i++) {
                for (int j = 0; j < N; j++) {
                    if (distance[i][j] > distance[i][k] + distance[k][j]) {
                        distance[i][j] = distance[i][k] + distance[k][j];
                    }
                }
            }
        }
        return distance;

    }

    /**
     * 结果打印
     *
     * @param header
     * @param floyd
     */
    public static void matrixPrint(char[] header, double[][] floyd) {
        System.out.print(" ");
        for (char c : header) {
            System.out.printf("%4s ,", c);
        }
        System.out.println();

        for (int i = 0; i < floyd.length; i++) {
            System.out.print(header[i]);
            System.out.println(Arrays.toString(floyd[i]));
        }
    }

    /**
     * 一般来说,边比较少,输入边的时候用table是比较方便的
     * 但floyd算法的运算用的是二维数组,所以还是需要转化到二维数组
     * 因为是无向图,所以一条边属于两个点,因此需要i,j查一次,j,i再查一次
     * 实在差不多,赋+∞
     *
     * @param header
     * @param weightedGraph
     * @return
     */
    public static double[][] tableToMatrix(char[] header, Table<Character, Character, Double> weightedGraph) {
        double[][] matrix = new double[header.length][header.length];
        for (int i = 0; i < header.length; i++) {
            for (int j = 0; j < header.length; j++) {
                char rowKey = header[i];
                char columnKey = header[j];
                Double weight = weightedGraph.get(rowKey, columnKey);
                if (weight != null) {
                    matrix[i][j] = weight;
                } else {
                    Double weight1 = weightedGraph.get(columnKey, rowKey);
                    if (weight1 != null) {
                        matrix[i][j] = weight1;
                    } else {
                        matrix[i][j] = infinity;
                    }
                }
            }
        }
        return matrix;
    }

    public static void main(String[] args) {
        char[] header = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L'};
        Table<Character, Character, Double> weightedGraph = HashBasedTable.create();
        weightedGraph.put('A', 'B', 17d);
        weightedGraph.put('A', 'D', 23d);
        weightedGraph.put('D', 'B', 42d);
        weightedGraph.put('C', 'B', 15d);
        weightedGraph.put('C', 'K', 24d);
        weightedGraph.put('K', 'L', 22d);
        weightedGraph.put('L', 'J', 17d);
        weightedGraph.put('K', 'J', 9d);
        weightedGraph.put('K', 'F', 11d);
        weightedGraph.put('C', 'F', 40d);
        weightedGraph.put('C', 'E', 31d);
        weightedGraph.put('E', 'H', 68d);
        weightedGraph.put('G', 'H', 18d);
        weightedGraph.put('F', 'J', 18d);
        weightedGraph.put('G', 'D', 12d);
        weightedGraph.put('J', 'H', 12d);
        weightedGraph.put('E', 'D', 5d);
        //自己到自己距离0
        for (char c : header) {
            weightedGraph.put(c, c, 0d);
        }


        double[][] matrix = tableToMatrix(header, weightedGraph);
        matrixPrint(header, matrix);
        double[][] floyd = floyd(matrix);
//
        matrixPrint(header, floyd);

    }
}

 

posted @ 2024-11-24 09:16  Mars.wang  阅读(10)  评论(0编辑  收藏  举报