Dijkstra(迪杰斯特拉)最短路径算法可视化演示

news2024/12/23 14:04:44

Dijkstra(迪杰斯特拉)算法,是一种解决带权图中单源最短路径的经典算法。它由荷兰计算机科学家 Edsger Dijkstra 于1956年提出。在现实生活中,这个算法被广泛应用于导航系统、网络路由等场景。

比如在地图导航中,城市可以看作图中的节点,道路可以看作边,路程或时间可以看作权重。Dijkstra 算法可以帮助我们找到从起点城市到其他所有城市的最短路径

Dijkstra 算法原理

Dijkstra 算法的核心思想是通过逐步扩展最短路径来找到从起点到所有其他节点的最短距离。它采用了一种贪心的策略,每次都选择当前未访问节点中距离最小的节点进行扩展。

算法维护两个关键的数据结构:一个记录最短距离的数组 dis,和一个记录已确定最短路径的顶点集合 T。初始时,将起点到自身的距离设为 0,到其他所有顶点的距离设为无穷大,集合 T 仅包含起点。

在每一轮迭代中,算法会从未确定最短路径的顶点中,选择当前 dis 数组中距离最小的顶点,将其加入集合 T。这个顶点的最短路径就此确定。接着,算法会以这个新加入的顶点为中转点,检查并更新从起点经过该顶点到达其他顶点的路径长度。如果通过这个中转点能得到一条更短的路径,就更新 dis 数组中对应顶点的距离值

这个过程会不断重复,直到以下任一条件满足时算法结束:

  1. 所有顶点都被加入到集合 T 中,表示所有可达顶点的最短路径都已确定;
  2. 剩余未访问顶点的距离值都为无穷大,表示这些顶点从起点不可达。

当算法结束时,dis 数组中存储的就是从起点到所有其他顶点的最短距离,其中距离为无穷大的顶点表示从起点无法到达该顶点。同时,通过记录路径中的前驱节点,我们还可以重建出所有可达顶点的具体最短路径。

有点难理解?没事,下面结合可视化工具来理解这个过程。

可视化操作指南

本Dijkstra 算法可视化工具比较强大,支持以下功能:

  • 可以在左上角选择起始节点,这里默认是 A 节点,可以选择不同的开始节点,来看看不同起始节点的路径有什么不同;
  • 双击连线可以修改边的权重,你可以修改权重,点击连线后,可以用 Del 键删除连线,或者点击节点后,可以用 Del 键删除节点。通过改变节点、连线、权重,来观察对最短路径的影响;
  • 算法执行过程中,最短路径会用绿色线条高亮显示,右侧实时显示权重矩阵和每一步的计算过程;
  • 支持一步步执行和自动执行,自动执行时,可以点击暂停按钮暂停执行;方便理解算法执行过程。

下面通过这个可视化工具,我们直观地理解 Dijkstra 算法是如何一步步找到最短路径的。当修改边的权重后,算法会重新计算,帮助我们理解不同权重对最短路径的影响。

具体查找最短路径过程

对于下面的无向图,我们选择 A 作为起始节点,来看看算法是如何一步步找到最短路径的。

点击下一步,第一步以 A 为起始点,记录了经过 A 到达各点的最短距离。
在这里插入图片描述

继续点击下一步,可以看到从上一步未访问的顶点中选择了距离最小的顶点,这里是距离为 4 的 D 顶点。

用 D 作为中转点,更新从 A 出发,经过 D 到达其他顶点的距离,如下图:
在这里插入图片描述

可以看到 B 和 E 的距离都更新了。 B 的距离从 10 更新为 6,E 的距离从无穷大更新为 4。

接着可以继续下一步,观察这里的搜索过程,看距离数字和已搜索顶点的变化过程。最后的结果如下:
在这里插入图片描述

Dijkstra 算法正确性证明

我们使用数学归纳法和反证法来证明 Dijkstra 算法的正确性。在算法执行到第 k 步时,已访问集合 T 中的每个节点 v 的距离 dist[v] 等于从起点到该节点的全局最短路径长度 short[v]

归纳证明过程如下:

1. 归纳基础:k = 1 时,T 中只包含起点 s,dist[s] = short[s] = 0,因此命题在 k = 1 时成立。

2. 归纳假设:假设命题在第 k 步时成立,即 T 中所有节点的 dist 值都是最短路径长度。

3. 归纳步骤:证明第 k+1 步时命题也成立:

  • 设第 k+1 步选择的节点为 v(v 是未访问节点中 dist 值最小的);v 与集合 T 中的某个节点 u 相连;
  • 需要证明:dist[v] = short[v]。

这里用反证法:

  • 假设存在一条从起点 s 到 v 的路径 P,其长度是 short[v],且 short[v] < dist[v]。
  • 由于起点 s 在集合 T 中,而终点 v 不在集合 T 中,路径 P 必然至少经过一个集合 T 中的节点(除起点外)。因为起点 s 到任何不在 T 中节点的距离,都是通过 T 中的节点来计算和更新的。
  • 设路径 P 上最后一个在集合 T 中的节点为 last,之后经过未访问集合中的节点 y 最终到达 v;下面看路径 P 的长度计算:
  short[v] = dist[last] + distance[last,y] + distance[y,v]  // 路径 P 的长度
           ≥ dist[y] + distance[y,v]                        // 根据 dist[y] 的更新规则
           ≥ dist[v]      

要理解下面这两个点才能明白上面的推导:

  1. 首先由归纳假设,到达 last 的距离 dist[last] 是最短的;对于节点 y,根据 Dijkstra 算法的更新规则:dist[y] ≤ dist[last] + distance[last,y]
  2. 又因为算法第 k+1 步选择了 v 作为当前最小距离节点,所以 dist[v] ≤ dist[y] + distance[y,v]。

于是就推导出 short[v] >= dist[v],这和我们的假设 short[v] < dist[v] 矛盾,因此假设不成立,dist[v] 就是从起点到 v 的最短路径长度。这也证明了算法每一步选择的节点的距离都是最短路径长度。

Dijkstra 算法要求非负权重

最后再顺便提下,Dijkstra 算法要求图中所有边的权重都必须是非负数。这是因为:

  1. 如果存在负权重边,算法的贪心策略可能会失效;
  2. 一旦确定某个顶点的最短路径后,可能会通过负权重边找到更短的路径,这违背了算法的基本假设:已确定的最短路径不会再被更新。

比如下面的图,存在负权重边 CE 为 -13,到 E 点的最短路径其实如图红色箭头 1,但是算法计算出来的还是 10:

在这里插入图片描述
对于带负权边的图,需要使用其他算法(如 Bellman-Ford 算法)来解决最短路径问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2264262.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

利用深度纹理实现全局雾效

1、为什么要实现屏幕后处理效果的全局雾效 既然Unity中已经提供了全局雾效&#xff0c;那为什么还要自己来实现呢&#xff1f;主要是因为Unity自带的全局雾效有以下几个缺点&#xff1a; 需要为每个自定义Shader按规则书写雾效处理代码自带的全局雾效无法实现一些自定义效果&…

解决“SVN无法上传或下载*.so、*.a等二进制文件“问题

今天&#xff0c;在使用Subversion提交代码到服务器时&#xff0c;发现无法提交*.a、*.so等二进制文件&#xff0c;右击这些文件&#xff0c;发现其属性为ignores。     问题原因&#xff1a;SVN的配置文件里&#xff0c;屏蔽了*.a、*.so文件的上传与下载&#xff0c;并把这些…

Linux下学 〖MySQL 〗表的属性之约束条件(下)(自增长auto_increament、唯一键unique key、外键foreign key)

绪论​ 每日激励&#xff1a;“不是看到希望才坚持&#xff0c;而是坚持了才有希望。—Jack” 绪论​&#xff1a; 本章是约束的下半篇&#xff0c;它将带你认识到一些在字段中非常常用的约束条件&#xff0c;自增长AUTO_CREMENT、唯一键UNIQUE KEY 和 外键FOREIGN KEY这三个。…

观察者模式(sigslot in C++)

大家&#xff0c;我是东风&#xff0c;今天抽点时间整理一下我很久前关注的一个不错的库&#xff0c;可以支持我们在使用标准C的时候使用信号槽机制进行观察者模式设计&#xff0c;sigslot 官网&#xff1a; http://sigslot.sourceforge.net/ 本文较为详尽探讨了一种观察者模…

内置函数.

日期函数 current_date/time() 日期/时间 获得年月日&#xff1a; 获得时分秒&#xff1a; 获得时间戳&#xff1a;日期时间 now()函数 体会date(datetime)的用法&#xff1a;只显示日期 在日期的基础上加日期&#xff1a;按照日历自动计算 关键字为 intervalinterval 后的数值…

web实验三

web实验三 三四个小时左右吧&#xff0c;做成功了学到新东西了&#xff0c;还是挺有趣的&#xff0c;好玩。还有些功能没做完&#xff0c;暂时这样了&#xff0c;要交了。 html <!DOCTYPE html> <html lang"en"><head><meta charset"UTF…

36. Three.js案例-创建带光照和阴影的球体与平面

36. Three.js案例-创建带光照和阴影的球体与平面 实现效果 知识点 Three.js基础 WebGLRenderer WebGLRenderer 是Three.js中最常用的渲染器&#xff0c;用于将场景渲染到网页上。 构造器 new THREE.WebGLRenderer(parameters)参数类型描述parametersobject可选参数&#…

windows平台小熊猫C++安装fmt库

前言 Windows安装C第三方库有点不容易&#xff0c;使用VS的可能还好点&#xff0c;有vcpkg工具用。使用其他工具的就麻烦了&#xff0c;因为基本上第三方库&#xff0c;都默认你是Linux平台&#xff0c;给的安装方式教程都是清一色Cmake&#xff0c;Windows上没有cmake&#x…

信号处理相关的东东(学习解惑)

信号处理相关的东东&#xff08;学习解惑&#xff09; 所有内容学习自知乎专栏&#xff0c;https://www.zhihu.com/column/xinhao&#xff0c;写的很好&#xff0c;值得反复学习 时频域分析的一些常用概念 FROM&#xff1a;https://zhuanlan.zhihu.com/p/35742606 1、相加性…

pset4filter less: helpers.c

&#xff08;&#xff14;&#xff09;blur function 简单画图熟悉一下要做什么 可以看到3种情况&#xff0c;顶格&#xff0c;边界&#xff0c;里面如果分开算的话&#xff0c;是真的麻烦&#xff1b;但是当时还真的没有想到更好的&#xff0c;就先写一写&#xff08;此处摘取…

3. Kafka入门—安装与基本命令

Kafka基础操作 一. 章节简介二. kafka简介三. Kafka安装1. 准备工作2. Zookeeper安装2.1 配置文件2.2 启动相关命令3. Kafka安装3.1 配置文件3.2 启动相关命令-------------------------------------------------------------------------------------------------------------…

某政银行APP登陆逆向

版本 V10.0.0 环境检测 {"xposed": {"action": "warn_and_exit","msg": {"zh_CN": "检测到您的设备安装有Xposed框架&#xff0c;存在非法攻击风险&#xff01;"},"button": {"zh_CN": &qu…

51c自动驾驶~合集42

我自己的原文哦~ https://blog.51cto.com/whaosoft/12888355 #DriveMM 六大数据集全部SOTA&#xff01;最新DriveMM&#xff1a;自动驾驶一体化多模态大模型&#xff08;美团&中山大学&#xff09; 近年来&#xff0c;视觉-语言数据和模型在自动驾驶领域引起了广泛关注…

算法题(12): 特殊年份

审题&#xff1a; 需要输出特殊年份的个数 思路&#xff1a; 获取数据&#xff1a;用字符串获取&#xff0c;然后全部加到总字符串s上判断 使用for循环对每一个四位数年分进行判断&#xff0c;如果是特殊年份就让负责记录的cou变量 解题&#xff1a; 注意&#xff1a;为什么我们…

RuoYi-Vue 数据权限控制示例nvliz (作业机器版)

目录 需求分析 ​编辑建表 代码编写 service层 Mapper层 测试 修改数据权限 添加数据 需求分析 建表 在若依的数据库中建立设备表&#xff1a;equipment 代码编写 使用代码生成&#xff0c;设备管理信息界面&#xff0c;如下图&#xff1a; 使用RuoYi的代码生成的功…

汽车IVI中控开发入门及进阶(三十八):手机投屏HiCar开发

手机投屏轻松实现手机与汽车的无缝连接,导航、音乐、通话等功能应有尽有,还支持更多第三方应用,让车载互联生活更加丰富多彩。 HiCar在兼容性和开放性上更具优势。 手机投屏可以说是车机的杀手级应用,大大拓宽了车机的可用性范围。其中华为推出的HiCar就是非常好用的一种。…

数据结构经典算法总复习(下卷)

第五章:树和二叉树 先序遍历二叉树的非递归算法。 void PreOrderTraverse(BiTree T, void (*Visit)(TElemType)) {//表示用于查找的函数的指针Stack S; BiTree p T;InitStack(S);//S模拟工作栈while (p || !StackEmpty(S)) {//S为空且下一个结点为空&#xff0c;意味着结束遍…

PID 控制算法理论背景:飞控领域的核心调控机制(1)

在飞控工程领域&#xff0c;PID 控制算法占据着极为关键的地位&#xff0c;是实现飞行器精确稳定控制的基石。PID 作为比例&#xff08;P&#xff09;、积分&#xff08;I&#xff09;、微分&#xff08;D&#xff09;的集成代表&#xff0c;构建起了控制系统的核心架构&#x…

插入排序与计数排序详解

在 C 编程中&#xff0c;排序算法是非常基础且重要的知识。今天我们就来深入探讨两种常见的排序算法&#xff1a;插入排序和计数排序&#xff0c;包括它们的代码实现、时间复杂度、空间复杂度、稳定性分析以及是否有优化提升的空间。 一、插入排序 插入排序&#xff08;Inser…

示波器--UNI-T 优利德 UT4102C 使用介绍

示波器--UNI-T 优利德 UT4102C 使用介绍 1 介绍图示特点 2 UTP04示波器探头&#xff08;100M带宽&#xff09;3 功能介绍4 示例RS232 电平信号测试 参考 1 介绍 图示 特点 2GS/s的实时采样率&#xff1a;设备能够以每秒2吉萨&#xff08;Giga Samples per second&#xff09;…