• 迪杰斯特拉算法处理无向图中最短路径的(dijkstra)Java实现(指定两点,求最短路径)




    其实不是原创哈,我写不出来。


          如何求图中V0到V5的最短路径呢?
            java实现的方式如下: 
           第一步,根据图来建立权值矩阵:
           int[][] W = { 
        {  0,   1,   4,  -1,  -1,  -1 },
        {  1,   0,   2,   7,    5,  -1 },
        {  4,   2,   0,  -1,    1,  -1 }, 
        { -1,  7,  -1,   0,    3,    2 },
        { -1,  5,    1,   3,   0,    6 }, 
        { -1, -1,  -1,   2,   6,    0 } };(-1表示两边不相邻,权值无限大)
    例如:W[0][2]=4 表示点V0到点V2的权值为4
    W[0][3]=-1表示点V0与V3不相邻,所以权值无限大。
    第二步:对V0标号;V0到其它点的路径得到 distance: {0,1,4,-1,-1,-1}; 找到V0到各点中权值最小的那个点(标号的点除外,-1代表无限大),故得到1即对应的下标1,得到V1;对V1标号,然后更改V0通过V1到其它点的路径得到 distance: { 0, 1, 3, 8, 6, -1}; 
    第三步:找到distance中权值最小的那个点,(标号的点除外)得到V2,对V2标号,然后更改V0通过V1->V2到其它点的路径得到 distance: { 0, 1, 3, 8, 4, -1}; 
    第四步:找到distance中权值最小的那个点,(标号的点除外)得到V4,对V4标号,然后更改V0通过V1->V2到其它点的路径得到 distance: { 0, 1, 3, 7, 4, 10}; 
    第四步:找到distance中权值最小的那个点,(标号的点除外)得到V3,对V3标号,然后更改V0通过V1->V2到其它点的路径得到 distance: { 0, 1, 3, 7, 4, 9}; 
    最后只剩下V5没有被标号,就找到V5了。结束!
    源代码如下:
    package com.xh.Dijkstra;  
     
    //这个算法用来解决无向图中任意两点的最短路径  
    public class ShortestDistanceOfTwoPoint_V5 {  
        public static int dijkstra(int[][] W1, int start, int end) {  
            boolean[] isLabel = new boolean[W1[0].length];// 是否标号  
            int[] indexs = new int[W1[0].length];// 所有标号的点的下标集合,以标号的先后顺序进行存储,实际上是一个以数组表示的栈  
            int i_count = -1;//栈的顶点  
            int[] distance = W1[start].clone();// v0到各点的最短距离的初始值  
            int index = start;// 从初始点开始  
            int presentShortest = 0;//当前临时最短距离  
     
            indexs[++i_count] = index;// 把已经标号的下标存入下标集中  
            isLabel[index] = true;  
              
            while (i_count<W1[0].length) {  
                // 第一步:标号v0,即w[0][0]找到距离v0最近的点  
     
                int min = Integer.MAX_VALUE;  
                for (int i = 0; i < distance.length; i++) {  
                    if (!isLabel[i] && distance[i] != -1 && i != index) {  
                        // 如果到这个点有边,并且没有被标号  
                        if (distance[i] < min) {  
                            min = distance[i];  
                            index = i;// 把下标改为当前下标  
                        }  
                    }  
                }  
                if (index == end) {//已经找到当前点了,就结束程序  
                    break;  
                }  
                isLabel[index] = true;//对点进行标号  
                indexs[++i_count] = index;// 把已经标号的下标存入下标集中  
                if (W1[indexs[i_count - 1]][index] == -1 
                        || presentShortest + W1[indexs[i_count - 1]][index] > distance[index]) {  
                    // 如果两个点没有直接相连,或者两个点的路径大于最短路径  
                    presentShortest = distance[index];  
                } else {  
                    presentShortest += W1[indexs[i_count - 1]][index];  
                }  
     
                // 第二步:将distance中的距离加入vi  
                for (int i = 0; i < distance.length; i++) {  
                    // 如果vi到那个点有边,则v0到后面点的距离加  
                    if (distance[i] == -1 && W1[index][i] != -1) {// 如果以前不可达,则现在可达了  
                        distance[i] = presentShortest + W1[index][i];  
                    } else if (W1[index][i] != -1 
                            && presentShortest + W1[index][i] < distance[i]) {  
                        // 如果以前可达,但现在的路径比以前更短,则更换成更短的路径  
                        distance[i] = presentShortest + W1[index][i];  
                    }  
     
                }  
            }  
            //如果全部点都遍历完,则distance中存储的是开始点到各个点的最短路径  
            return distance[end] - distance[start];  
        }  
        public static void main(String[] args) {  
            // 建立一个权值矩阵  
            int[][] W1 = { //测试数据1  
                    { 0, 1, 4, -1, -1, -1 },  
                    { 1, 0, 2, 7, 5, -1 },  
                    { 4, 2, 0, -1, 1, -1 },   
                    { -1, 7, -1, 0, 3, 2 },  
                    { -1, 5, 1, 3, 0, 6 },   
                    { -1, -1, -1, 2, 6, 0 } };  
            int[][] W = { //测试数据2  
                    { 0, 1, 3, 4 },  
                    { 1, 0, 2, -1 },  
                    { 3, 2, 0, 5 },  
                    { 4, -1, 5, 0 } };  
     
            System.out.println(dijkstra(W1, 0,4));  
     
        }  
    }  
    如果需要求无向图各个点的最短距离矩阵,则多次运用dijkstra算法就可以了,代码如下:
    package com.xh.Dijkstra;  
     
    //这个程序用来求得一个图的最短路径矩阵  
    public class ShortestDistance_V4 {  
        public static int dijkstra(int[][] W1, int start, int end) {  
            boolean[] isLabel = new boolean[W1[0].length];// 是否标号  
            int min = Integer.MAX_VALUE;  
            int[] indexs = new int[W1[0].length];// 所有标号的点的下标集合  
            int i_count = -1;  
            int index = start;// 从初始点开始  
            int presentShortest = 0;  
            int[] distance = W1[start].clone();// v0到各点的最短距离的初始值  
            indexs[++i_count] = index;// 把已经标号的下标存入下标集中  
            isLabel[index] = true;  
            while (true) {  
                // 第一步:标号v0,即w[0][0]找到距离v0最近的点  
     
                min = Integer.MAX_VALUE;  
                for (int i = 0; i < distance.length; i++) {  
                    if (!isLabel[i] && distance[i] != -1 && i != index) {  
                        // 如果到这个点有边,并且没有被标号  
                        if (distance[i] < min) {  
                            min = distance[i];  
                            index = i;// 把下标改为当前下标  
                        }  
                    }  
                }  
                if (index == end) {  
                    break;  
                }  
                isLabel[index] = true;  
                indexs[++i_count] = index;// 把已经标号的下标存入下标集中  
                if (W1[indexs[i_count - 1]][index] == -1 
                        || presentShortest + W1[indexs[i_count - 1]][index] > distance[index]) {  
                    presentShortest = distance[index];  
                } else {  
                    presentShortest += W1[indexs[i_count - 1]][index];  
                }  
     
                // 第二步:奖distance中的距离加入vi  
                for (int i = 0; i < distance.length; i++) {  
                    // 如果vi到那个点有边,则v0到后面点的距离加  
                    // 程序到这里是有问题滴! 呵呵  
                    if (distance[i] == -1 && W1[index][i] != -1) {// 如果以前不可达,则现在可达了  
                        distance[i] = presentShortest + W1[index][i];  
                    } else if (W1[index][i] != -1 
                            && presentShortest + W1[index][i] < distance[i]) {  
                        // 如果以前可达,但现在的路径比以前更短,则更换成更短的路径  
                        distance[i] = presentShortest + W1[index][i];  
                    }  
     
                }  
            }  
            return distance[end] - distance[start];  
        }  
       
        public static int[][] getShortestPathMatrix(int[][] W) {  
            int[][] SPM = new int[W.length][W.length];  
            //多次利用dijkstra算法  
            for (int i = 0; i < W.length; i++) {  
                for (int j = i + 1; j < W.length; j++) {  
                    SPM[i][j] =dijkstra(W, i, j);  
                    SPM[j][i] = SPM[i][j];  
                }  
            }  
            return SPM;  
        }  
     
        public static void main(String[] args) {  
            /* 顶点集:V={v1,v2,……,vn} */ 
            int[][] W = { { 0, 1, 3, 4 }, { 1, 0, 2, -1 }, { 3, 2, 0, 5 },  
                    { 4, -1, 5, 0 } };  
            int[][] W1 = { { 0, 1, 4, -1, -1, -1 }, { 1, 0, 2, 7, 5, -1 },  
                    { 4, 2, 0, -1, 1, -1 }, { -1, 7, -1, 0, 3, 2 },  
                    { -1, 5, 1, 3, 0, 6 }, { -1, -1, -1, 2, 6, 0 } };// 建立一个权值矩阵  
            ;// 建立一个权值矩阵  
            int[][] D = getShortestPathMatrix(W1);  
            //输出最后的结果  
            for (int i = 0; i < D.length; i++) {  
                for (int j = 0; j < D[i].length; j++) {  
                    System.out.print(D[i][j] + " ");  
                }  
                System.out.println();  
            }  
        }  
    }  

  • 相关阅读:
    Sqli-labs less 25a
    Sqli-labs less 26
    Sqli-labs less 26a
    Sqli-labs less 27
    Sqli-labs less 27a
    Sqli-labs less 28
    Sqli-labs less 28a
    Python3之sys模块
    Python3之os模块
    Python3之XML模块
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/3006133.html
Copyright © 2020-2023  润新知