【经典算法】最短路径算法——Dijkstra

🌈 个人主页:十二月的猫-CSDN博客
🔥 系列专栏: 🏀算法启示录

💪🏻 十二月的寒冬阻挡不了春天的脚步,十二点的黑夜遮蔽不住黎明的曙光 

目录

前言

松弛视角

伪代码展示

三角形理论 

 松弛操作可行性证明

迪杰斯特拉(Dijkstra)

一 前言

二 算法介绍

三 算法比较

 四 核心思想

五 算法步骤 

六 注意事项

七 伪代码 

总结


前言

最短路径算法是图论中一类重要算法,其功能就如名字一样——求解点与点之间最短距离。

首先,先让我们对最短路径算法有一个概观,看看都有哪些种类的最短路径算法,每一个种类中代表的算法又是什么。

单源最短路径算法:从一个起点出发求解其到其他所有其他点的最短距离

多源最短路径算法:从所有点出发求解其到其他所有其他点的最短距离 

本篇的迪杰斯特拉算法就属于单源最短路径算法 

松弛视角

关键点:

1、松弛和动态规划都是解决最短路径的方法。

2、松弛的本质就是对图固有属性三角理论的修正。

3、松弛和动态规划方法存在一定的重合,有时可以相互转化。两者并未有固定的优秀等次之分。

4、一些算法采用松弛视角解决,另一些采用动态规划视角来解决

伪代码展示

最短路径的求解包含两个步骤:一、初始化操作;二、松弛操作

松弛是最短路径求解过程中最好用的手段之一

两个操作的伪代码如下:

初始化操作:

INITIALIZE(G,s)
    for each vertex v ∈ G.V
        v.d=∞
        v.π=NULL
    s.d=0

松弛操作:

RELAX(u,v,w)
    if v.d>u.d+w(u,v)
        v.d=u.d+w(u,v)
        v.π=u

松弛操作的本质是对三角形理论的修正 

三角形理论 

定义:

对于任何边(u,v)∈E,都有d(s,v)<=d(s,u)+w(u,v)

d(s,v)表示s到v的最短路径

任何图都满足三角形理论,三角形理论是图形的固有性质

 松弛操作可行性证明

既然三角形理论是任何图形的固有性质。那么一旦一个图形中的出发源点s到目的点v的距离不符合三角形理论,那么就说明d(s,v)是不准确的(偏大),或者d(s,u)是不准确的(偏小)。显然我们初始化时令d(s,v)都是正无穷,所以d(s,u)偏小是不可能的。因此必然是d(s,v)偏大,需要修正。此时我们就令v.d=u.d+w(u,v),从而完成对d(s,v)的修正。

如果顶点v到s的距离满足三角形理论,那么此时的距离可能是正确的(即最短距离)。如果顶点v到s的距离经过所有其他顶点的三角形理论检验仍然满足,则说明此时得到的一定是正确的(即一定是最短距离)。

一次次的修正(松弛),点与点之间距离不断减少,直到最后得到最短路径。这就是松弛操作求解最短路径的可行性证明

较难理解!!但是希望大家可以好好看一遍

迪杰斯特拉(Dijkstra)

一 前言

动态规划和贪婪算法的一种不严谨的直观认识:

动态规划做出的结果在一次次循环中会发生改变;贪婪算法每次做出的结果(局部最优)就是全局最优,不会再发生改变

二 算法介绍

迪杰斯特拉算法是由荷兰计算机科学家在1956年发现的算法,此算法使用类似广度优先搜索的方法解决了带权图的单源最短路径问题。它是一个贪心算法

三 算法比较

与贝尔曼福特算法:

一、算法类型不同

迪杰斯特拉算法也是单源最短路径求解算法之一,和贝尔曼福特算法有相似的用途。不同的是贝尔曼福特算法是动态规划算法,前面做出的选择在后面可能更改;但是迪杰斯特拉算法是贪婪算法,每次做出的选择都是全局最优的,不会反复更改。

二、算法使用条件不同

迪杰斯特拉算法相比于贝尔曼福特算法是一种更特殊的算法,它只能用于没有负权重的带权图。而贝尔曼福特算法的适用图可以存在负权重,只是不能存在负权重回路。

三、算法运行效率不同

迪杰斯特拉算法是贪婪算法,所以运行效率高于贝尔曼福特算法

与BFS算法:

一、算法使用条件不同

广度优先搜索算法能够生成一棵树,并且这棵树上的所有点到树根的距离都是最短路径。但是BFS算法不可以处理存在权重的图,仅仅用于无权重的图

二、算法运行效率不同

BFS算法时间复杂度为O(V+E);迪杰斯特拉算法时间复杂度为O(VlgV+E);贝尔曼福特算法时间复杂度为O(VE)。考虑到一般情况下:E=V^2,所以贝尔曼福特算法复杂是最高的,其次是迪杰斯特拉算法,最后是BFS算法

注意点:在迪杰斯特拉和BFS算法中,E前面都不用乘V。但是在算法实现上,对边的访问是嵌套在点的访问V内的。要理解这个点,需要注意到对边的访问不是所有的边,而是点的邻边,这就代表遍历完所有点,访问的边也仅仅是E。所以这里E前面不用乘V

上面这三个时间复杂度,大家务必记住!!!最好能够理解,自己推导 

 四 核心思想

贪心策略:

每次选择一个点,这个点满足两个条件:1、未被访问过;二、到源点距离最短

这个点就是一个全局最优解!后续这个点到源点的距离是不需要修改的!!

贪心选择后的处理:

每次做出贪心选择后,贪心策略会影响后面子问题的最优解,所以在一些贪心问题中需要进行贪心选择后处理(贪心算法的必要条件是贪心选择后子问题仍有最优解)

处理:对于这个点的所有邻近点去尝试松弛 

五 算法步骤 

首先,设置两个集合A和B。A用来存放已经求出最短路径的点,B用来存放未计算最短路径的点(B中的点分为两类:一类无法到源点;另一类已经可以到源点但是不一定是最短路径)。其中B=V-A,实际上变量集合只有A一个。接下来就来做题吧~~~

 假设题目如下:


初始步:创建表格,将表格中所有点到源点的距离都设置为正无穷,顶点0到源点的距离设置为0

第一步:贪婪选择顶点0,加入集合A,得到 A集合为:{0},B集合为:{1,2,3,4,5,6}

第二步: 对和0邻接的所有点的执行松弛操作,此时,因为与0邻接的有1和2,并且到这两个点的距离,小于原来的∞距离,所以要将这两个点到0的距离都进行更新,如下图:

第三步: 从集合B{1,2,3,4,5,6}中,贪婪选择顶点2,加入集合A,得到 A集合为:{0,2},B集合为:{1,3,4,5,6},如下图:

第四步: 对和顶点2邻接的所有点的执行松弛操作,此时,因为与2邻接的有3和5,并且到这两个点的距离,小于原来的∞距离,所以要将这两个点到0的距离都进行更新,如下图:

后续操作和前面四步是相同的,直到所有点进入集合A算法停止

总结起来就是:

第一步:在距离表格中,贪婪选择新的点,将点加入集合A,得到全新的集合A和B

第二步:对与新点邻接的边执行松弛操作,得到新的表格 


六 注意事项

1.不能处理带有负权边的图(可能得不到最优解,认为是无法处理负权图),只能处理非负权图

如上图,更新顺序为:更新1,更新3,更新2。此时更新2后1的值更小了,这显然不符合贪婪选择(局部最优就是全局最优的结论)

2.只能解决单源最短路径问题


七 伪代码 

DIJKSTRA(G,w,s) //s用来记录访问的顺序,是需要返回的值;w边的权重集合
    S=空集合
    Q=G.V
    while(Q <> 空集合)
        u=EXTRACT-MIN(Q)
        S=S U {u}
        for each vertex v∈G.adj[u]
            RELEX(u,v,w) 

关键点:

1、EXTRACT-MIN的运行效率是决定整体运行效率的关键,最快可以达到lgn

2、Q在这里就是B集合,S就是A集合(也就是最后要输出的访问顺序)

3、RELEX操作本质就是利用三角理论对v的最短距离进行修正

总结

本文到这里就结束啦~~

本篇文章的撰写花了本喵两个多小时

如果仍有不够希望大家多多包涵~~如果觉得对你有帮助,辛苦友友点个赞哦~

知识来源:《算法导论》、山东大学孔凡玉老师ppt。不要用于商业用途转发哦~

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

GlaDS缘起

题目:Modeling channelized and distributed subglacial drainage in two dimensions 近年来,冰盖表面融化与冰盖动态之间的联系及其对海平面上升的影响引起了广泛关注。特别是格陵兰冰盖的研究显示,表面融水显著影响冰川移动速度,而冰下排水系统对冰川动力学及冰川水文学…

锂电池寿命预测 | Matlab基于SSA-SVR麻雀优化支持向量回归的锂离子电池剩余寿命预测

目录 预测效果基本介绍程序设计参考资料 预测效果 基本介绍 【锂电池剩余寿命RUL预测案例】 锂电池寿命预测 | Matlab基于SSA-SVR麻雀优化支持向量回归的锂离子电池剩余寿命预测&#xff08;完整源码和数据&#xff09; 1、提取NASA数据集的电池容量&#xff0c;以历史容量作…

《尚庭公寓》项目部署之Docker + Nginx

docker rmi nginx docker pull nginx docker rm -f nginx #先创建一个简易的nginx容器&#xff08;后面会删&#xff09;&#xff0c;然后通过 docker cp命令把容器里面的nginx配置反向拷贝到宿主主机上。 docker run --name nginx -p 80:80 -d nginx# 将容器nginx.conf文件复…

[ubuntu]docker 卡登录 You‘ve been signed out

Setting->Resources->Proxies设置当前使用的proxies即可 参考&#xff1a;https://github.com/docker/for-mac/issues/7160#issuecomment-2061040813

C++ 利用模板对不同类型的数组元素排序

一、问题描述&#xff1a; 使用template函数模板对一个长度为5的int数组和char数组元素进行排序&#xff08;升序&#xff09;。 二、代码&#xff1a; #include <iostream>using namespace std;template<typename T> void swapWWW(T &a, T &b) {T c a;…

乡村振兴与脱贫攻坚相结合:巩固拓展脱贫攻坚成果,推动乡村全面振兴,建设更加美好的乡村生活

目录 一、引言 二、巩固拓展脱贫攻坚成果 1、精准施策&#xff0c;确保稳定脱贫 2、强化政策支持&#xff0c;巩固脱贫成果 3、激发内生动力&#xff0c;促进持续发展 三、推动乡村全面振兴 1、加快产业发展&#xff0c;增强乡村经济实力 2、推进乡村治理体系和治理能力…

uniapp中父子组件的传值

1. uniapp中父子组件的传值 1.1. 父子组件的传值 通过props来实现, 子组件通过props来接收父组件传过来的值 1.1.1. 父组件 <!-- 父组件 --> <template><view><my-son :title"title" sendData"getSonData"></my-son><…

巧用docker+jmeter快速实现分布式百万级并发

分享背景 碰到的问题&#xff1a; 一个JMeter实例可能无法产生足够的负载来对你的应用程序进行压力测试&#xff5e; 解决办法&#xff1a; 1、修改jmeter配置文件里的内存堆 2、引入jmeter分布式压测 带来的问题&#xff1a; 如果我们要做分布式负载测试–我们需要1个…

win10下,python3.7安装xlrd和xlwt

win10下&#xff0c;执行import xlwt&#xff0c;结果报错 No module named xlwt。 原因&#xff1a;使用的python没有安装xlwt包。 解决方法&#xff1a; 1&#xff09;打开一个命令窗口&#xff0c;执行&#xff1a;where python&#xff0c;可以看到使用的python路径及版…

5.31.8 学习深度特征以实现判别定位

1. 介绍 尽管没有对物体的位置提供监督,但卷积神经网络 (CNN) 各层的卷积单元实际上可以充当物体检测器。尽管卷积层具有这种出色的物体定位能力,但当使用全连接层进行分类时,这种能力就会丧失。最近,一些流行的全卷积神经网络,如 Network in Network (NIN) [13] 和 Goog…

翘首以盼的抗锯齿

Antialiasing 实际的图形学中是怎么实现反走样的呢&#xff1f; 我们不希望实际产出的图形有锯齿效果&#xff0c;那怎么办呢&#xff1f; 从采样的理论开始谈起吧 Simpling theory 照片也是一种采样&#xff0c;把景象打散成像素放到屏幕上的过程&#xff1a; 还可以在不…

stm32 定时器输出比较(OC)与PWM的理解和应用

不积跬步&#xff0c;无以至千里&#xff1b;不积小流&#xff0c;无以成江海。大家好&#xff0c;我是闲鹤&#xff0c;公众号 xxh_zone&#xff0c;十多年开发、架构经验&#xff0c;先后在华为、迅雷服役过&#xff0c;也在高校从事教学3年&#xff1b;目前已创业了7年多&am…

盛夏之约,即将启程,2024中国北京消防展将于6月26举行

盛夏之约&#xff0c;即将启程&#xff0c;2024中国北京消防展将于6月26举行 盛夏之约&#xff0c;即将启程&#xff01;备受瞩目的2024中国&#xff08;北京&#xff09;消防技术与设备展览会将于6月26-28 日在北京.首钢会展中心盛大召开。作为消防安全和应急救援的年度盛会&…

DDMA信号处理以及数据处理的流程---DDMA原理介绍

Hello&#xff0c;大家好&#xff0c;我是Xiaojie&#xff0c;好久不见&#xff0c;欢迎大家能够和Xiaojie一起学习毫米波雷达知识&#xff0c;Xiaojie准备连载一个系列的文章—DDMA信号处理以及数据处理的流程&#xff0c;本系列文章将从目标生成、信号仿真、测距、测速、cfar…

LeetCode790多米诺和托米诺平铺

题目描述 有两种形状的瓷砖&#xff1a;一种是 2 x 1 的多米诺形&#xff0c;另一种是形如 “L” 的托米诺形。两种形状都可以旋转。给定整数 n &#xff0c;返回可以平铺 2 x n 的面板的方法的数量。返回对 109 7 取模 的值。平铺指的是每个正方形都必须有瓷砖覆盖。两个平铺…

【教程】从0开始搭建大语言模型:文本预处理

从0开始搭建大语言模型&#xff1a;文本预处理 参考仓库&#xff1a;LLMs-from-scratch 理解Word embedding 深度神经网络模型&#xff0c;包括LLM&#xff0c;不能直接处理原始文本&#xff0c;因此需要一种方法将它转换为连续值的向量&#xff0c;也就是embedding。如下图…

【YOLOV8】1.开发环境搭建

Yolo8出来一段时间了,包含了目标检测、实例分割、人体姿态预测、旋转目标检测、图像分类等功能,所以想花点时间总结记录一下这几个功能的使用方法和自定义数据集需要注意的一些问题,本篇是第一篇,开发环境的配置。 YOLO(You Only Look Once)是一种流行的物体检测和图像分割…

UE4_Ben_图形52_水下效果处理

学习笔记&#xff0c;不喜勿喷&#xff0c;欢迎指正&#xff0c;侵权立删&#xff01;祝愿生活越来越好&#xff01; 在这个后期处理的效果中&#xff0c;我们可以看到有很多不同的&#xff0c;这里有浓雾&#xff0c;波纹扭曲&#xff0c;镜头扭曲和边缘模糊&#xff0c;在第4…

Linux中安装Docker,并使用Docker安装MySQL和Redis

1、安装docker 1卸载系统之前的docker yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine2、安装Docker-CE #安装必须的依赖 sudo yum install -y yum-utils \device-map…

抽象,自定义函数,递归

6.1懒惰是一种美德 如果你 在一个地方编写了一些代码&#xff0c;但需要在另一个地方再次使用&#xff0c;该如何办呢&#xff1f; 假设你编写了一段代码&#xff0c;它计算一些斐波那契数&#xff08;一种数列&#xff0c;其中每个数都是前两个数的和&#xff09;。 现在的…