zoukankan      html  css  js  c++  java
  • 最短路+最短路条数+记录全部路径java实现

    package com.ltsj.web.meta.service.impl;
    
    import java.util.*;
    
    /**
     * @Author zl
     * @Description
     * @Date 2022/1/6 11:26
     */
    public class DijstraAlgorithm3 {
        /**
         * MAX_VALUE表示无穷大,代表两个网络节点距离不能到达
         * Double.MAX_VALUE,Double.MAX_VALUE相加会溢出导致出现负权
         */
        public static final double MAX_VALUE = Double.MAX_VALUE / 3;
    
        /**
         * 网络图节点个数
         */
        private static int n;
        /**
         * 网络边的邻接表
         */
        private static Edge[] edge;
        /**
         * 网络边的邻接表(反向邻接表,用于最短路径记录回溯)
         */
        private static Edge[] edge2;
    
        /**
         * 起点和终点
         */
        static int s, t;
        /**
         * 
         */
        static int[] head;
        /**
         * 
         */
        static int num;
        /**
         * num2
         */
        static int num2;
        /**
         * head2
         */
        static int[] head2;
    
        /**
         * 最短路径长度
         */
        static double[] dis;
        /**
         * 标记节点是否走过
         */
        static boolean[] vis;
        /**
         * 记录最短路径(多条)
         */
        static Set<List<Integer>> se;
    
        /** 
         * 数据初始化
         * @author: zl
         * @date: 2022/1/6 17:40
         */
        static void init(double[][] matrix) {
            n = matrix.length;
            head = new int[n * n];
            head2 = new int[n * n];
            dis = new double[n];
            vis = new boolean[n];
            se = new HashSet<>();
            edge = new Edge[n * n];
            edge2 = new Edge[n * n];
            
            for (int i = 0; i < n; i++) {
                head[i] = -1;
                head2[i] = -1;
            }
            num = 0;
            num2 = 0;
    
    
        }
    
        /** 
         * 求最短路
         * @param st: 
         * @return: void
         * @author: zl
         * @date: 2022/1/6 17:41
         */
        public static void dijstra(int st) {
            for (int i = 0; i < n; i++) {
                dis[i] = MAX_VALUE;
                vis[i] = false;
            }
            dis[st] = 0;
            Queue<Node> que = new PriorityQueue<>();
            que.add(new Node(st, 0));
            while (!que.isEmpty()) {
                Node p = que.element();
                que.poll();
                int nown = p.num;
                if (vis[nown])
                    continue;
                vis[nown] = true;
                for (int i = head[nown]; i != -1; i = edge[i].next) {
                    Edge e = edge[i];
                    if (dis[e.v] > dis[nown] + e.w && !vis[e.v]) {
                        dis[e.v] = dis[nown] + e.w;
                        que.add(new Node(e.v, dis[e.v]));
                    }
                }
            }
        }
    
    
        /** 
         * 最短路径计算
         * @param t: 
         * @param vec: 
         * @return: void
         * @author: zl
         * @date: 2022/1/6 17:41
         */
        static void prinPath(int t, List<Integer> vec) {
            vec.add(t);
            if (t == DijstraAlgorithm3.s) {
                Collections.reverse(vec);
                se.add(vec);
                vec = new ArrayList<>();
                vec.add(DijstraAlgorithm3.t);
                return;
            }
            for (int i = head2[t]; i != -1; i = edge2[i].next) {
                int v = edge2[i].v;
                double w = edge2[i].w;
                if (dis[v] == dis[t] - w) {
                    //System.out.println(v+"----"+t);
                    prinPath(v, vec);
                    vec = new ArrayList<>();
                    vec.add(t);
                }
            }
        }
    
    
        static void addEdge(int u, int v, double w) {
            Edge newEdge = new Edge(u, v, head[u], w);
            edge[num] = newEdge;
            head[u] = num++;
        }
    
    
        static void addEdge2(int u, int v, double w) {
            Edge newEdge = new Edge(u, v, head2[u], w);
            edge2[num2] = newEdge;
            head2[u] = num2++;
        }
    
    
        static class Node implements Comparable<Node> {
            int num;//存编号
            double val;  //和距离
    
            public Node() {
                this.num = 0;
                this.val = 0;
            }
    
            public Node(int num, double val) {
                this.num = num;
                this.val = val;
            }
    
            @Override
            public int compareTo(Node o) {
                if (val > o.val) {
                    return 1;
                } else if (val < o.val) {
                    return -1;
                } else {
                    return 0;
                }
            }
        }
    
        static class Edge {
            int u, v, next;
            double w;
    
            public Edge() {
            }
    
            public Edge(int u, int v, int next, double w) {
                this.u = u;
                this.v = v;
                this.next = next;
                this.w = w;
            }
    
            @Override
            public String toString() {
                return "Edge{" +
                        "u=" + u +
                        ", v=" + v +
                        ", next=" + next +
                        ", w=" + w +
                        '}';
            }
        }
    
        public static void main(String[] args) {
    
          /*  double[][] matrix = {{0, 5, 2, 6,-1},
                    {-1,0,-1,-1 ,1},
                    {-1, 1, 0, 3,5},
                    {-1,-1,-1, 0,2},
                    {-1,-1,-1,-1,0}};*/
            double[][] matrix = new double[][]{
                    {0, 1, -1, 1, -1, -1},
                    {1, 0, 1, -1, 1, -1},
                    {-1, 1, 0, -1, -1, 1},
                    {1, -1, -1, 0, 1, -1},
                    {-1, 1, -1, 1, 0, 1},
                    {-1, -1, 1, -1, 1, 0}
            };
    
            init(matrix);
            for (int i = 0; i < matrix.length; i++) {
                for (int j = 0; j < matrix.length; j++) {
                    if (matrix[i][j] < 0) {
                        matrix[i][j] = MAX_VALUE / 3;
                    }
                    if (i != j) {
                        addEdge(i, j, matrix[i][j]);
                        addEdge2(j, i, matrix[i][j]);
                    }
    
                }
            }
            //起点到终点
            s = 0;
            t = 4;
            //调用dijstra算法计算最短路径
            dijstra(s);
    
            System.out.println("The least distance from " + s + "->" + t + " is " + dis[t]);
            List<Integer> vec = new ArrayList<>();
            prinPath(t, vec);
            System.out.println("最短路径有:" + se.size() + "条");
            for (List<Integer> ans : se) {
                for (int i = 0; i < ans.size() - 1; i++) {
                    System.out.print(ans.get(i) + "->");
                }
                System.out.println(ans.get(ans.size() - 1));
            }
            System.out.println(Arrays.toString(edge));
            System.out.println(Arrays.toString(edge2));
    
        }
    }

     附:

    测试方法中的图模型:

    1:

     2:

    心有所想,必有回响
  • 相关阅读:
    解决Android的ListView控件滚动时背景变黑
    倒计时实现网页跳转
    java获取当前路径
    JavaScript笔记之面向对象
    Jqery调用WebService(.Net3.5环境下)
    Android开发:TabActivity中onKeyDown无法响应的解决方法
    最近不知道什么时候开始D3D11CreateDevice返回E_FAIL
    C++ allocator及一些影响程序性能的因素
    AOP切面编程 几年前写的,移过来
    Adaptive Transparency
  • 原文地址:https://www.cnblogs.com/zhulei2/p/15772183.html
Copyright © 2011-2022 走看看