数据结构与算法 26 弗洛伊德算法

弗洛伊德(Floyd)算法

  • 用于寻找给定的加权图中各个顶点间的最短路径,时间复杂度较高:立方阶,将每个顶点都看作是出发点,求到其它点的最短距离

  • 狄杰斯特拉算法是计算图中某一个顶点到其它顶点的最短路径,选定被访问顶点


算法思路

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

中间顶点 出发顶点 终点


代码

  1. 创建图类class Graph{} 定义变量 构造器 展示pre和dis数组的方法

    class Graph{
        private char[] vertex; // store vertex
        private int[][] dis; // store distance of each vertex to other vertexes
        private int[][] pre; // store pre vertex of arrived target vertex
    
        /**
         * constructor
         * @param length size
         * @param matrix preliminary matrix
         * @param vertex
         */
        public Graph(int length,int[][] matrix,char[] vertex){
            this.vertex = vertex;
            this.dis = matrix;
            this.pre = new int[length][length];
            // initialize pre array (index of pre vertex)
            for(int i = 0;i<length;i++){
                Arrays.fill(pre[i],i);
            }
        }
    
        // show pre and dis
        public void show(){
            char[] vertex = {'A','B','C','D','E','F','G'};
            for(int k = 0; k < dis.length;k++){
                // output one row of pre
                for(int i = 0;i<dis.length;i++){
                    System.out.print(vertex[pre[k][i]]+" ");
                }
                System.out.println();
                // output one row of dis
                for(int i = 0;i<dis.length;i++){
                    System.out.print("(shortest dis of "+vertex[k]+" and B: "+ dis[k][i]+") ");
                }
                System.out.println();
                System.out.println();
            }
        }
    }
    
  2. 主函数测试图

    public static void main(String[] args) {
            // test graph
            char[] vertex = {'A','B','C','D','E','F','G'};
            // preliminary matrix
            int[][] matrix = new int[vertex.length][vertex.length];
            final int N = 65535;
            matrix[0] = new int[]{0,5,7,N,N,N,2};
            matrix[1] = new int[]{5,0,N,9,N,N,3};
            matrix[2] = new int[]{7,N,0,N,8,N,N};
            matrix[3] = new int[]{N,9,N,0,N,4,N};
            matrix[4] = new int[]{N,N,8,N,0,5,4};
            matrix[5] = new int[]{N,N,N,4,5,0,6};
            matrix[6] = new int[]{2,3,N,N,4,6,0};
            // create graph object
            Graph graph = new Graph(vertex.length, matrix, vertex);
            graph.show();
        }
    
  3. 弗洛伊德(class Graph{}中)

    public void floyd(){
            int len = 0; // store dis
            // traverse middle vertex, k is the index of middle vertex; ['A','B','C'...]
            for(int k = 0;k<dis.length;k++){ //
                // start from vertex i['A','B','C'...]
                for(int i = 0;i<dis.length;i++){
                    // end vertex
                    for(int j = 0;j<dis.length;j++){
                       len = dis[i][k] + dis[k][j];
                       // distance: start from i, pass by k, arrive at j
                        if(len<dis[i][j]){
                            dis[i][j] = len; // update dis
                            pre[i][j] = pre[k][j]; // update pre
                        }
                    }
                }
            }
        }
    
  4. 主函数中调用弗洛伊德方法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值