两点间最短间隔 - Dijkstra

打印 上一主题 下一主题

主题 909|帖子 909|积分 2727

一、汇总

算法场景说明参考
BFS
无权图的搜刮
标准BFS默认搜刮一条最短路径
改造后可以输出全部最短路径
https://blog.csdn.net/m0_37145844/article/details/144534202
DFS走迷宫重要利用回溯算法思想,不包管最短路径https://blog.csdn.net/m0_37145844/article/details/144534202
  1. Dijkstra
复制代码
带权图最短路径的经典解法重要利用贪心思想,其中在u打印路径时候包含递归,回溯等思想本篇解说
二、Dijkstra 原理

借助java工具类:PriorityQueue 默认内部元素逼迫根据指定规则举行自然排序的的小顶堆,每次选择下层节点到起点开始算的最小权值的节点作为当前节点,举行向外的下一个层级的探索,最终让全部节点都保存了,此节点从开始节点的最小权重值及其最短路径的父节点。
三、Dijkstra 代码实现-Java版本

有必要解说一下代码结构:

  • 内部类的利用

    • 表现更强的封装性,结构体仅供外部类利用,不对外袒露。
    • 外部类可以直接调用内部类,简化代码。
    • 内部类也可以直接利用外部类的成员变量,此例子中暂无表现。

  • 优先级队列的利用

    • 比力器的构造。
    • 因为每次向外层探索时候,都会加入下一层到开始节点权重总和最小的节点,此数据结构逼迫举行排序,序列化为一个小顶堆。这也是提升此算法性能的关键设计。
    • 默认为小顶堆。
    • 间隔Map和路径反向记录Map,都表现了算法设计的技巧。
    • 尤其在打印路径时候,最终用递归思想。

  1. package algo.backtrace.Dijkstra.weiwei;
  2. import java.util.*;
  3. public class Dijkstra {
  4.     class Grap {
  5.         // 带权重的无向图表示,邻接矩阵表示
  6.         Map<Integer, List<Edag>> adjList;
  7.         Grap() {
  8.             adjList = new HashMap<>();
  9.         }
  10.         // 添加边
  11.         public void addEdag(int start, int des, int weight) {
  12.             adjList.putIfAbsent(start, new ArrayList<>());
  13.             adjList.putIfAbsent(des, new ArrayList<>());
  14.             adjList.get(start).add(new Edag(des, weight));
  15.             adjList.get(des).add(new Edag(start, weight));
  16.         }
  17.         // 获取一个顶点的所有边
  18.         public List<Edag> getEdags(int node) {
  19.             return adjList.getOrDefault(node, new ArrayList<>());
  20.         }
  21.         // 获取所有顶点
  22.         public Set<Integer> getAllNodes() {
  23.             return adjList.keySet();
  24.         }
  25.     }
  26.     // 描述边
  27.     class Edag{
  28.         int des;
  29.         int weight;
  30.         Edag(int des, int weight) {
  31.             this.des = des;
  32.             this.weight = weight;
  33.         }
  34.     }
  35.     public Map<Integer, Integer> dijkstra(Grap grap, Integer start) {
  36.         // 定义工具
  37.         PriorityQueue<int[]> pq = new PriorityQueue<>(Comparator.comparing(a -> a[1]));
  38.         Map<Integer, Integer> dist = new HashMap<>();
  39.         Map<Integer, Integer> prev = new HashMap<>();
  40.         // 初始化参数
  41.         for (Integer node : grap.getAllNodes()) {
  42.             dist.put(node, Integer.MAX_VALUE);
  43.             prev.put(node, -1);
  44.         }
  45.         dist.put(start, 0);
  46.         pq.offer(new int[]{start, 0});
  47.         while (!pq.isEmpty()) {
  48.             int[] poll = pq.poll();
  49.             int currNode = poll[0];
  50.             int currWeight = poll[1];
  51.             if (currWeight > dist.get(currNode)) {
  52.                 continue;
  53.             }
  54.             for (Edag edag : grap.getEdags(currNode)) {
  55.                 int newDist = currWeight + edag.weight;
  56.                 if (newDist < dist.get(edag.des)) {
  57.                     dist.put(edag.des, newDist);
  58.                     prev.put(edag.des, currNode);
  59.                     pq.offer(new int[]{edag.des, newDist});
  60.                 }
  61.             }
  62.         }
  63.         System.out.println("dist:" + dist);
  64.         System.out.println("prev:" + prev);
  65.         return prev;
  66.     }
  67.     public void printTrace(Map<Integer, Integer> prevMap, int traget, List<Integer> trace) {
  68.         if (prevMap.get(traget) == -1) {
  69.             return;
  70.         }
  71.         traget = prevMap.get(traget);
  72.         printTrace(prevMap, traget, trace);
  73.         trace.add(traget);
  74.     }
  75.     public void main(String[] args) {
  76.         Grap grap = new Grap();
  77.         grap.addEdag(0,1,4);
  78.         grap.addEdag(0,2,1);
  79.         grap.addEdag(1,3,2);
  80.         grap.addEdag(2,3,8);
  81.         grap.addEdag(2,4,3);
  82.         grap.addEdag(4,5,2);
  83.         grap.addEdag(3,5,1);
  84.         Dijkstra dijkstra = new Dijkstra();
  85.         Map<Integer, Integer> prevMap = dijkstra.dijkstra(grap, 0);
  86.         List<Integer> list = new ArrayList<>();
  87.         dijkstra.printTrace(prevMap, 5, list);
  88.         System.out.println(list);
  89.     }
  90. }
  91. // 输出
  92. // dist:{0=0, 1=4, 2=1, 3=6, 4=4, 5=6}
  93. // prev:{0=-1, 1=0, 2=0, 3=1, 4=2, 5=4}
  94. // [0, 2, 4] 瑕疵之处是traget 没有打印出,无伤大雅。
复制代码


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

去皮卡多

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表