首页 > 编程语言 >最短路径问题的Dijastra算法

最短路径问题的Dijastra算法

时间:2024-03-06 19:11:40浏览次数:30  
标签:distance arr Dijastra int 最短 算法 edge new 节点

求节点间最短路径的Dijastra算法

  • 思路概述

    给定一个权值非负的有向连通图, 求某个特定原点(假定节点编号为0)到终点的最短路径权值之和。

    Dijastra算法采用贪心思想, 每次选取最短距离可到达的点确定对应路径权值之和, 并用以更新其它邻接点的可到达最短距离直至确定终点或者所有节点的最短路径值。

  • 具体步骤

    每次选取可到达的最短距离节点有两种常见方式: 暴力查找最小值或者基于小根堆实现, 这里介绍基于堆的具体步骤

    1. 定义distance数组记录当前可到达每个节点已知的最短距离, 初始只能确定distance[0]=0, 其它节点距离为无穷大; 定义visited数组标记节点是否从堆中弹出过;
    2. 小根堆中维护int[2]数组, arr[0]表示节点编号, arr[1]表示到达该节点时的距离, 初始值将原点对应的[0, 0]加入堆;
    3. 从堆顶取出上一轮维护的所有可到达节点中距离最短的值, 如果该节点没有从堆中弹出过, 说明当前弹出的距离就是该节点的最短路径距离; 如果弹出过就忽略这组继续弹出下一组数据处理;
    4. 遍历当前节点其它边, 如果当前节点最短距离加上边的权值小于边另一端点v已知的最短距离且节点v未从堆中弹出过, 就更新distance[v]的值并将[v, distance[v]]加入堆中用于更新下一轮最短距离的节点信息;
    5. 重复3~4步骤直至目标节点或者所有节点的最短距离都已确定, 即堆中元素全部弹出。
  • 数据示例

    用[u, v, distance]表示的图: [[0,6,7], [0,1,2], [1,2,3], [1,3,3], [6,3,3], [3,5,1], [6,5,1], [2,5,3], [0,4,5], [4,6,2]]

    PS: 下表中堆中数据按升序展示而不是按底层数据顺序。

    堆顶弹出的元素 堆中元素 更新后的distance数组 更新后的堆 visited数组
    [0, 0] -- [0, 2, ∞, ∞, 5, ∞, 7] [1, 2]
    [4, 5]
    [6, 7]
    [1, 0, 0, 0, 0, 0, 0]
    [1, 2] [4, 5]
    [6, 7]
    [0, 2, 5, 5, 5, ∞, 7] [4, 5]
    [2, 5]
    [3, 5]
    [6, 7]
    [1, 1, 0, 0, 0, 0, 0]
    [4, 5] [2, 5]
    [3, 5]
    [6, 7]
    [0, 2, 5, 5, 5, ∞, 7] [2, 5]
    [3, 5]
    [6, 7]
    [1, 1, 0, 0, 1, 0, 0]
    [2, 5] [3, 5]
    [6, 7]
    [0, 2, 5, 5, 5, 8, 7] [3, 5]
    [6, 7]
    [5, 8]
    [1, 1, 1, 0, 1, 0, 0]
    [3, 5] [6, 7]
    [5, 8]
    [0, 2, 5, 5, 5, 6, 7] [5, 6]
    [6, 7]
    [5, 8]
    [1, 1, 1, 1, 1, 0, 0]
    [5, 6] [6, 7]
    [5, 8]
    [0, 2, 5, 5, 5, 6, 7] [6, 7]
    [5, 8]
    [1, 1, 1, 1, 1, 1, 0]
    [6, 7] [5, 8] [0, 2, 5, 5, 5, 6, 7] [5, 8] [1, 1, 1, 1, 1, 1, 1]
    [5, 8] -- 已弹出过,忽略 -- [1, 1, 1, 1, 1, 1, 1]
  • 代码示例

      /**
      * n: 节点总数
      * edges: 以[u, v, distance]表示的双向图数据
      */
      public void process(int n, int[][] edges) {
          int[] distance = new int[n];
          
          boolean[] visited = new boolean[n];
          List<int[]> graph = new List[n];// 邻接表
          for (int i = 0; i < n; i++) {
              distance[i] = Integer.MAX_VALUE;
              graph[i] = new ArrayList<>();
          }
          distance[0] = 0;
          for (int[] edge : edges) {
              graph[edge[0]].add(new int[]{edge[1], edge[2]});
              graph[edge[1]].add(new int[]{edge[0], edge[2]});
          }
    
          PriorityQueue<int[]> heap = new PriorityQueue<>(Comparator.comparingInt(arr -> arr[1]));
          heap.add(new int[]{0, 0});
          while (heap.size() > 0) {
              int[] arr = heap.poll();
              int u = arr[0], d = arr[1];
              if (visited[u]) {
                  continue;
              }
              visited[u] = true;
              for (int[] edge : graph[u]) {
                  int v = edge[0];
                  if (!visited[v] && distance[v] > d + edge[1]) {
                      distance[v] = d + edge[1];
                      heap.add(new int[]{v, distance[v]})
                  }
              }
          }
      }
    

标签:distance,arr,Dijastra,int,最短,算法,edge,new,节点
From: https://www.cnblogs.com/coding-memory/p/18057345

相关文章

  • TCP 中的 Delay ACK 和 Nagle 算法
    哈喽大家好,我是咸鱼。今天分享一篇大佬的文章,作者:卡瓦邦噶!文章链接:https://www.kawabangga.com/posts/5845教科书介绍的TCP内容通常比较基础:包括三次握手,四次挥手,数据发送通过收到ACK来保证可靠传输等等。当时我以为已经学会了TCP,但是后来在工作中,随着接触TCP越来越多,我......
  • vslam算法
    vslam算法VSLAM(VisualSimultaneousLocalizationandMapping)算法是一种用于机器人自主导航的技术,它允许机器人通过视觉传感器获取环境信息,以估计自己的位姿和周围环境的的三维重建。VSLAM算法可以分为以下几类:1特征法。这种方法通过提取图像中......
  • slam算法
    slam算法SLAM(SimultaneousLocalizationandMapping,同时定位与地图构建)算法是一种集成了传感器测量和计算机视觉技术的自主导航技术,它允许机器人或无人机在未知环境中实时构建地图,并估计自己的位置和方向。SLAM算法可以分为基于视觉的SLAM和基于激光雷达或......
  • 代码随想录算法训练营day14 | leetcode 144. 二叉树的前序遍历、145. 二叉树的后序遍
    目录题目链接:144.二叉树的前序遍历-简单题目链接:145.二叉树的后序遍历-简单题目链接:94.二叉树的中序遍历-简单递归三要素:确定递归函数的参数和返回值:确定哪些参数是递归的过程中需要处理的,那么就在递归函数里加上这个参数,并且还要明确每次递归的返回值是什么进而确定递归......
  • 代码随想录算法训练营第三十八天| ● 理论基础 ● 509. 斐波那契数 ● 70. 爬楼梯
    理论基础 代码随想录(programmercarl.com)动态规划的五部曲:确定dp数组(dptable)以及下标的含义确定递推公式dp数组如何初始化确定遍历顺序举例推导dp数组斐波那契数 题目链接:509.斐波那契数-力扣(LeetCode)思路:还好。classSolution{public:intfib(intn)......
  • 代码随想录算法训练营第三十八天 | 746. 使用最小花费爬楼梯,、70. 爬楼梯,509. 斐波那
     509.斐波那契数 已解答简单 相关标签相关企业 斐波那契数 (通常用 F(n) 表示)形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和。也就是:F(0)=0,F(1)=1F(n)=F(n-1)+F(n-2),其中n>......
  • 代码随想录算法训练营第一天| 704. 二分查找、27. 移除元素。
    704.二分查找https://leetcode.cn/problems/binary-search/description/一、左闭右闭`//左闭右闭publicstaticinterFen1(int[]nums,inttarget){if(target<nums[0]||target>nums[nums.length-1]){return-1;}intmaxIndex=nums.length-......
  • 代码随想录算法训练营第三十七天 | 738. 单调递增的数字,968.监控二叉树
    968.监控二叉树 已解答困难 相关标签相关企业 给定一个二叉树,我们在树的节点上安装摄像头。节点上的每个摄影头都可以监视其父对象、自身及其直接子对象。计算监控树的所有节点所需的最小摄像头数量。 示例1:输入:[0,0,null,0,0]输出:1......
  • 算法随笔——图论:无向图三/四元环计数
    参考:https://oi-wiki.org/graph/rings-count/题目链接:P1989无向图四元环计数求四元环步骤:建双向边。给每条边定向,由度数小的点指向大的,若度数一样则看编号大小。此时只有这几种情况:都可以归类为:枚举起始点A,枚举A<-->B(双向边),枚举B-->C,让C点被访问次数\(cnt\)......
  • MATLAB数据挖掘用改进的K-Means(K-均值)聚类算法分析高校学生的期末考试成绩数据
    全文链接:http://tecdat.cn/?p=30832原文出处:拓端数据部落公众号本文首先阐明了聚类算法的基本概念,介绍了几种比较典型的聚类算法,然后重点阐述了K-均值算法的基本思想,对K-均值算法的优缺点做了分析,回顾了对K-均值改进方法的文献,最后在Matlab中应用了改进的K-均值算法对数据进行了......