当前位置: 首页 > article >正文

【图论】Dijkstra算法求最短路

一、Dijkstra算法简介

Dijkstra算法是由河南荷兰计算机科学家狄克斯特拉(Dijkstra)于1959年提出的,因此又叫狄克斯特拉算法。

二、初识Dijkstra算法

在使用Dijkstra算法求最短路时,需要用到三个辅助数组:
v i s x vis_x visx:布尔数组,给 x x x 号结点打标记。初始化为 0 0 0
s t e p x step_x stepx:记录从固定起点到 x x x 号结点的最短路径,初始化为 + ∞ +\infty +
p r e x pre_x prex:记录 x x x 号结点的前一个结点,如果不理解前一个结点是什么意思,第三部分模拟过程中会讲解。

三、模拟Dijkstra算法求最短路径长度

首先看下面的图5。
图5
图5

假设我们要求从 0 0 0 号结点到 4 4 4 号结点的最短距离,下面是模拟过程:

  1. 初始化 v i s vis vis s t e p step step 数组,记录起点 s t e p 0 = 0 step_0=0 step0=0
  2. 找到目前未被标记的 s t e p step step 值最小的结点 0 0 0,标记 v i s 0 = 1 vis_0=1 vis0=1 0 0 0 号结点的邻接点有 1 1 1 7 7 7,边权分别为 4 4 4 8 8 8,记录 s t e p 1 = m i n ( s t e p 1 , s t e p 0 + 4 ) = 4 step_1=min(step_1,step_0+4)=4 step1=min(step1,step0+4)=4 s t e p 7 = m i n ( s t e p 7 , s t e p 0 + 8 ) = 8 step_7=min(step_7,step_0+8)=8 step7=min(step7,step0+8)=8 p r e 1 = 0 pre_1=0 pre1=0 p r e 7 = 0 pre_7=0 pre7=0
  3. 找到目前未被标记的 s t e p step step 值最小的结点 1 1 1,标记 v i s 1 = 1 vis_1=1 vis1=1 1 1 1 号结点的邻接点有 2 2 2 7 7 7,边权分别为 8 8 8 11 11 11,记录 s t e p 2 = m i n ( s t e p 2 , s t e p 1 + 8 ) = 12 step_2=min(step_2,step_1+8)=12 step2=min(step2,step1+8)=12 s t e p 7 = m i n ( s t e p 7 , s t e p 1 + 11 ) = 8 step_7=min(step_7,step_1+11)=8 step7=min(step7,step1+11)=8 p r e 2 = 1 pre_2=1 pre2=1(PS:此处因为 8 ≤ 15 8 \leq 15 815,所以无需对 s t e p 7 step_7 step7 p r e 7 pre_7 pre7 的值进行修改);
  4. 找到目前未被标记的 s t e p step step 值最小的结点 7 7 7,标记 v i s 7 = 1 vis_7=1 vis7=1 7 7 7 号结点的邻接点有 1 1 1 6 6 6 8 8 8,边权分别为 11 11 11 1 1 1 7 7 7,记录 s t e p 1 = m i n ( s t e p 1 , s t e p 7 + 11 ) = 4 step_1=min(step_1,step_7+11)=4 step1=min(step1,step7+11)=4 s t e p 6 = m i n ( s t e p 6 , s t e p 7 + 1 ) = 9 step_6=min(step_6,step_7+1)=9 step6=min(step6,step7+1)=9 s t e p 8 = m i n ( s t e p 8 , s t e p 7 + 7 ) = 15 step_8=min(step_8,step_7+7)=15 step8=min(step8,step7+7)=15 p r e 6 = 7 pre_6=7 pre6=7 p r e 8 = 7 pre_8=7 pre8=7
  5. 找到目前未被标记的 s t e p step step 值最小的结点 6 6 6,标记 v i s 6 = 1 vis_6=1 vis6=1 6 6 6 号结点的邻接点有 5 5 5 7 7 7 8 8 8,边权分别为 2 2 2 1 1 1 6 6 6,记录 s t e p 5 = m i n ( s t e p 5 , s t e p 6 + 2 ) = 11 step_5=min(step_5,step_6+2)=11 step5=min(step5,step6+2)=11 s t e p 7 = m i n ( s t e p 7 , s t e p 6 + 1 ) = 8 step_7=min(step_7,step_6+1)=8 step7=min(step7,step6+1)=8 s t e p 8 = m i n ( s t e p 8 , s t e p 6 + 6 ) = 15 step_8=min(step_8,step_6+6)=15 step8=min(step8,step6+6)=15 p r e 5 = 6 pre_5=6 pre5=6
  6. 找到目前未被标记的 s t e p step step 值最小的结点 5 5 5,标记 v i s 5 = 1 vis_5=1 vis5=1 5 5 5 号结点的邻接点有 2 2 2 3 3 3 4 4 4 6 6 6,边权分别为 4 4 4 14 14 14 10 10 10 2 2 2,记录 s t e p 2 = m i n ( s t e p 2 , s t e p 5 + 4 ) = 12 step_2=min(step_2,step_5+4)=12 step2=min(step2,step5+4)=12 s t e p 3 = m i n ( s t e p 3 , s t e p 5 + 14 ) = 25 step_3=min(step_3,step_5+14)=25 step3=min(step3,step5+14)=25 s t e p 4 = m i n ( s t e p 4 , s t e p 5 + 10 ) = 21 step_4=min(step_4,step_5+10)=21 step4=min(step4,step5+10)=21 s t e p 6 = m i n ( s t e p 6 , s t e p 5 + 2 ) = 9 step_6=min(step_6,step_5+2)=9 step6=min(step6,step5+2)=9 p r e 3 = 5 pre_3=5 pre3=5 p r e 4 = 5 pre_4=5 pre4=5
  7. 找到目前未被标记的 s t e p step step 值最小的结点 2 2 2,标记 v i s 2 = 1 vis_2=1 vis2=1 2 2 2 号结点的邻接点有 1 1 1 3 3 3 5 5 5 8 8 8,边权分别为 8 8 8 7 7 7 4 4 4 2 2 2,记录 s t e p 1 = m i n ( s t e p 1 , s t e p 2 + 8 ) = 4 step_1=min(step_1,step_2+8)=4 step1=min(step1,step2+8)=4 s t e p 3 = m i n ( s t e p 3 , s t e p 2 + 7 ) = 19 step_3=min(step_3,step_2+7)=19 step3=min(step3,step2+7)=19 s t e p 5 = m i n ( s t e p 5 , s t e p 2 + 4 ) = 11 step_5=min(step_5,step_2+4)=11 step5=min(step5,step2+4)=11 s t e p 8 = m i n ( s t e p 8 , s t e p 2 + 2 ) = 14 step_8=min(step_8,step_2+2)=14 step8=min(step8,step2+2)=14 p r e 3 = 5 pre_3=5 pre3=5 p r e 8 = 2 pre_8=2 pre8=2
  8. 找到目前未被标记的 s t e p step step 值最小的结点 8 8 8,标记 v i s 8 = 1 vis_8=1 vis8=1 8 8 8 号结点的邻接点有 2 2 2 6 6 6 7 7 7,边权分别为 2 2 2 6 6 6 7 7 7,记录 s t e p 2 = m i n ( s t e p 2 , s t e p 8 + 2 ) = 12 step_2=min(step_2,step_8+2)=12 step2=min(step2,step8+2)=12 s t e p 6 = m i n ( s t e p 6 , s t e p 8 + 6 ) = 9 step_6=min(step_6,step_8+6)=9 step6=min(step6,step8+6)=9 s t e p 7 = m i n ( s t e p 7 , s t e p 8 + 7 ) = 11 step_7=min(step_7,step_8+7)=11 step7=min(step7,step8+7)=11
  9. 找到目前未被标记的 s t e p step step 值最小的结点 3 3 3,标记 v i s 3 = 1 vis_3=1 vis3=1 3 3 3 号结点的邻接点有 2 2 2 4 4 4 5 5 5,边权分别为 7 7 7 9 9 9 14 14 14,记录 s t e p 2 = m i n ( s t e p 2 , s t e p 3 + 7 ) = 12 step_2=min(step_2,step_3+7)=12 step2=min(step2,step3+7)=12 s t e p 4 = m i n ( s t e p 4 , s t e p 3 + 9 ) = 21 step_4=min(step_4,step_3+9)=21 step4=min(step4,step3+9)=21 s t e p 5 = m i n ( s t e p 5 , s t e p 3 + 7 ) = 14 step_5=min(step_5,step_3+7)=14 step5=min(step5,step3+7)=14
  10. 找到目前未被标记的 s t e p step step 值最小的结点 4 4 4,标记 v i s 4 = 1 vis_4=1 vis4=1 4 4 4 号结点的邻接点有 3 3 3 5 5 5,边权分别为 9 9 9 10 10 10,记录 s t e p 3 = m i n ( s t e p 3 , s t e p 4 + 9 ) = 19 step_3=min(step_3,step_4+9)=19 step3=min(step3,step4+9)=19 s t e p 5 = m i n ( s t e p 5 , s t e p 4 + 10 ) = 11 step_5=min(step_5,step_4+10)=11 step5=min(step5,step4+10)=11
  11. 此时我们发现,所有结点都已经被标记过,结束搜索,起点 0 0 0 到终点 4 4 4 的最短距离为 s t e p 4 = 21 step_4=21 step4=21

四、模拟Dijkstra算法求最短路径

仍以上面的图5为例,搜索过程略。
从终点 x = 4 x=4 x=4 往回遍历,每遍历到一个结点就将其入栈,然后 x = p r e x x=pre_x x=prex。当遍历到起点 0 0 0 入栈后,结束遍历,输出栈。
得到结果 0 → 7 → 6 → 5 → 4 0 \rightarrow 7 \rightarrow 6 \rightarrow 5 \rightarrow 4 07654
代码将于2024年九月底完成,目前不予展示。
如果博客有错误,请联系我,我会尽快修正!鲁A济南车!


http://www.kler.cn/news/290274.html

相关文章:

  • 【源码】Sharding-JDBC源码分析之ContextManager创建中ShardingSphereDatabase的创建原理
  • 注册安全分析报告:熊猫频道
  • centos 安装使用aria2
  • 数据分析处理库(pandas)
  • 802.11 中 scrambler的matlab仿真
  • Oracle中的临时表Temporary Table
  • [数据集][目标检测]课堂行行为检测数据集VOC+YOLO格式4065张12类别
  • 【2024最新】Adobe Lightroom Classic安装教程(直接使用)
  • 【算法每日一练及解题思路】判断字符串是否包含数字
  • K8S CronJob
  • 跨域问题及解决方案
  • 鸿萌数据恢复服务:VMWare 虚拟机无法访问,该怎样解决?
  • C++中(Qt)类与命名空间
  • 数据结构07
  • idea2021安装教程与常见配置(可激活至2099年)
  • el-select在火狐浏览器中 点击搜索框聚焦时会有一个蓝色的框
  • 新电脑Win11系统想要降级为Win10怎么操作?
  • torchvision库学习之transforms.Compose(模块)
  • 【Java基础】代理
  • Your Diffusion Model is Secretly a Zero-Shot Classifier论文阅读笔记
  • 农事管理系统
  • 守护夏日清凉:EasyCVR+AI视频智能管理方案为水上乐园安全保驾护航
  • 爬虫 可视化 管理:scrapyd、Gerapy、Scrapydweb、spider-admin-pro、crawllab、feaplat、XXL-JOB
  • Linux云计算学习笔记10 (打包压缩与解包)
  • CSS 中的element()函数
  • AVL树调整平衡及旋转详解
  • MATLAB-绘图系列(第一期)
  • 线程间数据传递之ThreadLocal、InheritableThreadLocal、TransmittableThreadLocal
  • 性能、成本与 POSIX 兼容性比较: JuiceFS vs EFS vs FSx for Lustre
  • ElasticSearch和Kibana的安全设置以及https设置