LiSi... 2022-11-04 00:43 采纳率: 0%
浏览 17

Java求最小路径问题

img


其它地方找不到答案,来这里试一下。希望有好兄弟能给出思路,最好能有具体代码,谢谢

  • 写回答

1条回答 默认 最新

  • 技术宅program 2022-11-04 10:50
    关注

    迪杰斯特拉(Dijkstra)算法应该可以

    迪杰斯特拉(Dijkstra)算法是典型最短路径算法,用于计算一个结点到其他结点的最短路径。它的主要特点是以起始点为中心向外层层扩展(广度优先搜索思想),直到扩展到终点为止。

    例子可以看下

    img

    import java.util.Arrays;
    
    /**
     * @author zs
     * @version 1.0.0
     * @ClassName DijkstraAlgorithm.java
     * @Description TODO 迪杰斯特拉算法--最短路径问题(如何计算出 G 村庄到 其它各个村庄的最短距离)
     * @createTime 2022年11月04日 12:52:00
     */
    public class DijkstraAlgorithm {
        public static void main(String[] args) {
            char[] vertex = {'A', 'B', 'C', 'D', 'E', 'F', 'G'};
            //邻接矩阵
            int[][] matrix = new int[vertex.length][vertex.length];
            final int N = 65535;// 表示不可以连接
            matrix[0] = new int[]{N, 5, 7, N, N, N, 2};
            matrix[1] = new int[]{5, N, N, 9, N, N, 3};
            matrix[2] = new int[]{7, N, N, N, 8, N, N};
            matrix[3] = new int[]{N, 9, N, N, N, 4, N};
            matrix[4] = new int[]{N, N, 8, N, N, 5, 4};
            matrix[5] = new int[]{N, N, N, 4, 5, N, 6};
            matrix[6] = new int[]{2, 3, N, N, 4, 6, N};
    
            Graph graph = new Graph(vertex, matrix);
            graph.showGraph();
            graph.dsj(6);
            graph.showDijkstra();
        }
    }
    
    class Graph {
        private char[] vertex;
        private int[][] matrix;
        private VisitedVertex vv;
    
        // 构造器
        public Graph(char[] vertex, int[][] matrix) {
            this.vertex = vertex;
            this.matrix = matrix;
        }
    
        //显示结果
        public void showDijkstra() {
            vv.show();
        }
    
        // 显示结果
        public void showGraph() {
            for (int[] link : matrix) {
                System.out.println(Arrays.toString(link));
            }
        }
    
        //迪杰斯特拉算法实现
    
        /**
         * @param index 表示出发顶点对应的下标
         */
    
        public void dsj(int index) {
            vv = new VisitedVertex(vertex.length, index);
            update(index); //更新 index 顶点到周围顶点的距离和前驱顶点
            for (int i = 1; i < vertex.length; i++) {
                index = vv.updateArr(); // 选择并返回新的访问顶点
                update(index); ; // 更新 index 顶点到周围顶点的距离和前驱顶点
            }
        }
    
        //更新 index 下标顶点到周围顶点的距离和周围顶点的前驱顶点,
        public void update(int index) {
            int len = 0;
            for (int j = 0; j < matrix[index].length; j++) {
                // len 含义是 : 出发顶点到 index 顶点的距离 + 从 index 顶点到 j 顶点的距离的和
                len = vv.getDis(index) + matrix[index][j];
                // 如果 j 顶点没有被访问过,并且 len 小于出发顶点到 j 顶点的距离,就需要更新
                if (!vv.in(j) && len < vv.getDis(j)) {
                    vv.updatePre(j, index);
                    vv.updateDis(j, len);
                }
            }
    
        }
    
    }
    
    class VisitedVertex {
        // 记录各个顶点是否访问过 1 表示访问过,0未访问,会动态更新
        public int[] already_arr;
        // 每个下标对应的值为前一个顶点下标, 会动态更新
        public int[] pre_visited;
        // 记录出发顶点到其他所有顶点的距离,比如 G 为出发顶点,就会记录 G 到其它顶点的距离,会动态更新,求的最短距离就会存放到 dis
        public int[] dis;
    
        //构造器
    
        /**
         * @param length :表示顶点的个数
         * @param index: 出发顶点对应的下标, 比如 G 顶点,下标就是 6
         */
        public VisitedVertex(int length, int index) {
            this.already_arr = new int[length];
            this.pre_visited = new int[length];
            this.dis = new int[length];
            // 初始化dis数组
            Arrays.fill(dis, 65535);
            this.already_arr[index] = 1; //设置出发顶点被访问过
            this.dis[index] = 0; //设置出发顶点的访问距离为 0
    
        }
    
        /**
         * 功能: 判断 index 顶点是否被访问过
         *
         * @param index
         * @return 如果访问过,就返回 true, 否则访问 false
         */
        public boolean in(int index) {
            return this.already_arr[index] == 1;
        }
    
        /**
         * 功能: 更新出发顶点到 index 顶点的距离
         *
         * @param index
         * @param len
         */
        public void updateDis(int index, int len) {
            this.dis[index] = len;
        }
    
        /**
         * 功能: 更新 pre 这个顶点的前驱顶点为 index 顶点
         *
         * @param pre
         * @param index
         */
        public void updatePre(int pre, int index) {
            this.pre_visited[pre] = index;
        }
    
        /**
         * 功能:返回出发顶点到 index 顶点的距离
         *
         * @param index
         */
        public int getDis(int index) {
            return this.dis[index];
        }
    
        /**
         * 继续选择并返回新的访问顶点, 比如这里的 G 完后,就是 A 点作为新的访问顶点(注意不是出发顶点)
         *
         * @return
         */
        public int updateArr() {
            int min = 65535, index = 0;
            for (int i = 0; i < this.already_arr.length; i++) {
                if (already_arr[i] == 0 && dis[i] < min) {
                    min = dis[i];
                    index = i;
                }
            }
            already_arr[index] = 1;
            return index;
        }
    
        //显示最后的结果
        //即将三个数组的情况输出
        public void show() {
            System.out.println("==========================");
            //输出 already_arr
            for (int i : already_arr) {
                System.out.print(i + " ");
            }
            System.out.println();
            //输出 pre_visited
            for (int i : pre_visited) {
                System.out.print(i + " ");
            }
            System.out.println();
            //输出 dis
            for (int i : dis) {
                System.out.print(i + " ");
            }
            System.out.println();
            //为了好看最后的最短距离,我们处理
            char[] vertex = {'A', 'B', 'C', 'D', 'E', 'F', 'G'};
            int count = 0;
            for (int i : dis) {
                if (i != 65535) {
                    System.out.print(vertex[count] + "(" + i + ") ");
                } else {
                    System.out.println("N ");
                }
                count++;
            }
            System.out.println();
    
        }
    
    
    }
    
    评论

报告相同问题?

问题事件

  • 创建了问题 11月4日

悬赏问题

  • ¥15 问题遇到的现象和发生背景 360导航页面千次ip是20元,但是我们是刷量的 超过100ip就不算量了,假量超过100就不算了 这是什么逻辑呢 有没有人能懂的 1000元红包感谢费
  • ¥30 计算机硬件实验报告寻代
  • ¥15 51单片机写代码,要求是图片上的要求,请大家积极参与,设计一个时钟,时间从12:00开始计时,液晶屏第一行显示time,第二行显示时间
  • ¥15 用C语言判断命题逻辑关系
  • ¥15 原子操作+O3编译,程序挂住
  • ¥15 使用STM32F103C6微控制器设计两个从0到F计数的一位数计数器(数字),同时,有一个控制按钮,可以选择哪个计数器工作:需要两个七段显示器和一个按钮。
  • ¥15 在yolo1到yolo11网络模型中,具体有哪些模型可以用作图像分类?
  • ¥15 AD9910输出波形向上偏移,波谷不为0V
  • ¥15 淘宝自动下单XPath自动点击插件无法点击特定<span>元素,如何解决?
  • ¥15 曙光1620-g30服务器安装硬盘后 看不到硬盘