【图论】Dijkstra算法求最短路

news/2024/9/19 22:45:56/ 标签: 算法, 图论, 数据结构

一、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.ppmy.cn/news/1520483.html

相关文章

【Python百日进阶-Web开发-音频】Day703 - librosa快速入门

文章目录 一、概述二、快速开始三、高级用法 https://librosa.org/doc/latest/tutorial.html 本节介绍使用librosa进行开发的基础知识,包括包概述、基本和高级用法以及与scikit-learn 包的集成。我们将假设您对 Python 和 NumPy/SciPy 有基本的了解。 一、概述 li…

Python开发学习之Python和Excel的数据实现互通

今天为大家分享一篇使用Python和Excel的数据实现互通的技巧心得,可以让Python和Excel的数据实现互通!具有很好的参考价值,希望对大家有所帮助(建议在电脑端阅读,代码案例较多)。一起过来看看吧!…

重要通知! | Paraverse平行云GitHub搬家啦!

随着“平行云”更名为“Paraverse平行云”,我们的GitHub地址也做出了相应调整。欢迎开发者访问我们的新地址,继续共享我们的开源仓库与实时云渲染软件! 更改的核心内容如下: pingxingyun >> ParaverseTechnology * 文档…

RS232转RS485

1.232转485转换器 232转485转换器是RS-232与RS-485之间的双向接口的转换器,应用于主控机之间,主控机与单片机或外设之间构成点到点,点到多点远程多机通信网络,实现多机应答通信,广泛地应用于工业自动化控制系统&#x…

SpringBoot + Vue实现websocket

后端代码 pom.xml增加依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId> </dependency> 增加ServerEndpointExporter Bean import org.springframework.context.…

Moveit2 Move Group C++ 接口

系列文章目录 留空 文章目录 系列文章目录前言一、完整代码二、编写步骤三、代码分析1. 引入必要的头文件2. 初始化和配置 ROS2 环境3. 设置 MoveIt 规划组和场景4. 可视化5. 获取基本信息6. 开始演示7. 规划姿态目标8. 可视化计划路径9. 移动到姿势目标10. 规划关节空间目标1…

Linux下TCP编程

一.概念介绍 1.socket 是什么&#xff1f; socket&#xff08;套接字&#xff09;本质上是一个抽象的概念&#xff0c;它是一组用于网络通信的 API&#xff0c;提供了一种统一的接口&#xff0c;使得应用程序可以通过网络进行通信。在不同的操作系统中&#xff0c;socket 的实…

Datawhale X李宏毅苹果书进阶 AI夏今营 task03学习笔记

batch normalization(批次标准化&#xff09; batch normalization--Tarining 直接改error surface的landscape&#xff0c;把山“铲平”有时候尽管error surface是个“碗”&#xff0c;都不见得好train。如下图所示&#xff1a; w1,w2对loss的斜率差别很大&#xff0c;w1方…

Redis基本类型常用命令练习

目录 一、String类型 1. 使用Redis的String命令&#xff0c;如何设置一个键为"username"&#xff0c;值为"Tom"的键值对&#xff1f; 2. 如何使用Redis的String命令获取键为"username"的值&#xff1f; 3. 使用Redis的String命令&#xff0c…

基于Python的机器学习系列(23):奇异值分解(SVD)

在本篇中&#xff0c;我们将介绍如何利用奇异值分解&#xff08;SVD&#xff09;进行降维。SVD 是一种强大的矩阵分解方法&#xff0c;可以帮助我们提取数据中的重要特征&#xff0c;广泛应用于数据分析、图像处理等领域。 问题定义 在数据分析中&#xff0c;特别是当数据维度…

IDEA向mysql写入中文字符时出现乱码问题

可参考该博客&#xff1a;https://www.cnblogs.com/bb1008/p/7704458.html 第一步是将IDEA软件中的编码方式全部改为utf8 File -> Settings -> Editor -> File Encodings 第二步是在数据库链接中加入 ?characterEncodingUTF-8

使用Python写一个适用于Dify和FastGPT的JsonPath插件

编写适用于 Dify 和 FastGPT 的 JsonPath 插件 在本文中&#xff0c;我将分享如何编写一个适用于 AI应用平台的 JsonPath 插件&#xff0c;该插件能够处理 JSON 数据的路径查询、正则表达式提取&#xff0c;以及 JavaScript 沙盒执行功能。这个插件的主要目的是让用户能够通过…

kubeadm方式升级k8s集群

一、注意事项 升级前最好备份所有组件及数据&#xff0c;例如etcd 不要跨两个大版本进行升级&#xff0c;可能会存在版本bug&#xff0c;如&#xff1a; 1.19.4–>1.20.4 可以 1.19.4–>1.21.4 不可以 跨多个版本的可以逐个版本进行升级。 二、查看当前版本 [rootk8s…

8逻辑回归的代价函数

8.1逻辑回归中的代价函数 成本函数 损失函数 8.2逻辑回归的简化版代价函数 代价函数的简化 损失函数的简化 方框内的式子等于上面的

Cadence Virtuoso添加工艺库、转换工艺库格式

系统环境&#xff1a;Red Hat 操作软件&#xff1a;Virtuoso 工艺库&#xff1a;tsmc18rf 1、准备好工艺库文件&#xff0c;放在任意文件夹内&#xff0c;记住文件路径&#xff1a; 2、打开Virtuoso软件&#xff1a; 在桌面右键打开终端&#xff0c;输入&#xff1a; virtuo…

Oracle SQL和PL/SQL中SQL%ROWCOUNT和SQL%FOUND属性

在Oracle SQL和PL/SQL中&#xff0c;SQL%ROWCOUNT和SQL%FOUND是两个常用的属性&#xff0c;它们各自在不同的上下文中提供关于最近执行的DML&#xff08;数据操纵语言&#xff09;语句&#xff08;如INSERT、UPDATE、DELETE&#xff09;或SELECT INTO语句的反馈信息。尽管这两个…

Scott Brinker:Martech中的AI会让买家体验更好还是更糟?这取决于…….

Martech中的AI会让买家体验更好还是更糟&#xff1f; 你怎么知道自己正处于炒作周期的顶峰&#xff1f;当手段大于目的。 Martech专业人士和营销运营领导者正被推动将人工智能应用于营销——将其用于任何事情&#xff01;——相信人工智能的自动化和加速&#xff0c;尤其是生…

AI 大模型在文本生成任务中的创新应用

概述 随着人工智能技术的飞速发展&#xff0c;大模型在文本生成任务中的应用越来越广泛。这些模型通过深度学习技术&#xff0c;能够生成连贯、有意义的文本&#xff0c;甚至在某些情况下达到与人类写作难以区分的程度。本文将探讨AI大模型在文本生成任务中的创新应用&#xf…

zsh 的补全系统

在 Zsh 中&#xff0c;自动提醒&#xff08;自动补全&#xff09;功能通常由 zsh 的补全系统&#xff08;zsh-completions&#xff09;和 zsh-autosuggestions 等插件提供。如果你的 Zsh 不再自动提醒了&#xff0c;可以通过以下步骤来检查和启用这些功能。 1. 确保补全系统已…

Azure OpenAI Ingesion Job API returns 404 Resource not found

题意&#xff1a;Azure OpenAI Ingestion Job API 返回 404 资源未找到。 问题背景&#xff1a; Im following the documentation from Azure on the ingestion job API here: Ingestion Jobs - Create - REST API (Azure Azure AI Services) | Microsoft Learn 我正在按照Az…