【图论】迪杰特斯拉算法

文章目录

  • 迪杰特斯拉算法
    • 主要特点
    • 基本思想
    • 算法步骤
    • 示例
  • 实现迪杰斯特拉算法
    • 基本步骤
    • 算法思路
  • 总结

在这里插入图片描述

迪杰特斯拉算法

迪杰特斯拉算法是由荷兰计算机科学家艾兹赫尔·迪杰特斯拉(Edsger W. Dijkstra)在1956年提出的,用于解决单源最短路径问题的经典算法。该算法的目标是从一个起始顶点找到到图中其他顶点的最短路径。

主要特点

  • 适用于带权图,其中权重为非负数。(为什么只适用于非负数,因为迪杰斯特拉的思想是贪心测量,当有负权引入的时候,贪心策略将不再适用)
  • 解决从单个源点到其他所有顶点的最短路径问题。
  • 时间复杂度:当使用优先队列(例如堆)时,复杂度为 O ( E log ⁡ V ) O(E \log V) O(ElogV),其中 V V V 为顶点数量, E E E 为边的数量。

基本思想

Dijkstra算法通过不断探索距离最近的顶点,逐步扩展其最短路径的已知范围,直到找到从源点到所有其他顶点的最短路径。该算法基于贪心策略:每一步选择尚未处理的、距离源点最近的顶点进行扩展。

算法步骤

  1. 初始化

    • 将起始顶点的距离设为0,其余所有顶点的距离设为∞(表示不可达)。
    • 使用一个优先队列(或最小堆)来存储顶点及其当前的最短距离。
  2. 取距离源点最近的顶点,并标记为已处理。

  3. 对于该顶点的每个邻接顶点,更新其最短距离(如果通过当前顶点可以获得更短的路径,则更新距离)。

  4. 重复步骤2和3,直到所有顶点都被处理过,或优先队列为空。

示例

在这里插入图片描述

实现迪杰斯特拉算法

基本步骤

首先假设我们有如下的一个图:
在这里插入图片描述
灰色的点代表起点,我们需要从起点开始算每个点到起点的最短路径。
第一步按照迪杰斯特拉的表述应该将起点到起点的最短路径初始化为0,起点到另外其他点的距离初始化为正无穷。
在这里插入图片描述
这里我们更新完s点之后,应该更新和s点相连的点的最短路径了,由于之前s到t点和到y点的最短路径是正无穷,由于st和sy都小于两个最短路径,所以更新两个最短路径。
在这里插入图片描述
根据贪心策略,更新出来的两个最短路径,sy更小,所以我们应该更新y相连的路径。
在这里插入图片描述
所以接下来我们应该更新y连接的点的最短路径。
在这里插入图片描述
由于原本s到t的最短路径是10,但是现在的最短路径更新了之后是8,所以更新结果,由于之前s到x的最短路径是正无穷,所以现在将最短路径更新为14,s到z 也是相同的,因为之前的最短路径是正无穷,所以现在将最短路径更新为7.
在这三条最短路径中选择最短的那条:
在这里插入图片描述
这里就应该以z为新的起点
在这里插入图片描述
更新z连接的顶点,z一共有两条边,一条是zs,一条是zx,由于s到s是最近的0,所以这里不需要更新,由于之前s到x的距离是14,所以这里更新s到x的距离。
接下来再从剩下的边中,选择最小的路径。
在这里插入图片描述
从t点开始只有一条路径,所以这里t到x,tx是1,由于之前的st的最短路径是8,所以此时的最短路径是9,9<13所以这里应该更新最短路径为9
在这里插入图片描述
这里最短路径算是更新完了。

算法思路

由于这里我们涉及到最短路径,所以应该开辟一个dist数组,我们来想一想一个dist数组是否能解决问题,很显然是不能的,我们还需要一个数组,记录当前最短路径的前一个顶点的下标,在遍历的时候我们可以索引每一个顶点了。
代码展示:

void Dijkstra(const V& src, vector<W>& dist, vector<int>& pPath)
{//获取起点的下标size_t srci = GetVertexIndex(src);//确定节点的数量size_t n = _vertexs.size();dist.resize(n, MAX_W);pPath.resize(n, MAX_W);//自己到自己的距离是0dist[srci] = 0;//自己的前一个是自己pPath[srci] = srci;//已经确定最短路径的顶点的集合vector<bool> S(n, false);for(size_t j=0;j<n;j++){//选择最短路径顶点且不在s中更新其他路径int u = 0;     //最小的那个点W min = MAX_W; //最小权值for (size_t i = 0;i < n;i++){if (S[i] == false && dist[i] < min){//选出最小的点u = i;//更新最小权值min = dist[i];}}//u被选出来S[u] = true;//松弛更新u连接出去的顶点v    srci->u   u->vfor (size_t v = 0;v < n;v++){//确定u连接出去的所有边if (S[v] == false && _matrix[u][v] != MAX_W && (dist[u] + _matrix[u][v]) < dist[v]){dist[v] = dist[u] + _matrix[u][v];//将v的父亲更新为upPath[v] = u;}}}
}

打印路径节点和最短路径:

//打印最短路径
void PrinrtShotPath(const V& src, vector<W>& dist, vector<int>& pPath)
{//获取起点的下标size_t srci = GetVertexIndex(src);//确定节点的数量size_t n = _vertexs.size();for (size_t i = 0;i < n;i++){if (i != srci){// 先找出i顶点的路径vector<int> path;size_t parenti = i;//先将自己存进去(自己不是原点先push进去)while (parenti != srci){path.push_back(parenti);parenti = pPath[parenti];}path.push_back(srci);//将路径逆置reverse(path.begin(), path.end());//打印出路径for (auto e : path){cout << _vertexs[e] << "->";}//打印最短路径cout << dist[i];cout << endl;}}
}

因为根据最后一个节点去推上一个节点,推完之后数组中的节点会是一个反着的路径,所以在打印的时候,应该先把数组逆置,逆置之后再进行打印。

总结

在本文中,我们深入探讨了迪杰斯特拉算法的原理与应用。作为一种经典的最短路径算法,迪杰斯特拉算法通过优先队列有效地解决了从单一源点到其他所有节点的最短路径问题。我们分析了其时间复杂度和空间复杂度,了解了在不同图形结构下的性能表现。

通过示例和实现,我们不仅掌握了算法的基本步骤,还体验了其在实际应用中的重要性。无论是在交通导航、网络路由还是各种优化问题中,迪杰斯特拉算法都发挥着不可或缺的作用。

希望本文能够帮助你更好地理解迪杰斯特拉算法,并为你在图论和算法领域的进一步学习打下坚实的基础。如果你有任何疑问或想法,欢迎在评论区与我交流!

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

web开发(1)-基础

这是对b站课程的总结&#xff0c;后续可能会继续更 01 前后端分离介绍_哔哩哔哩_bilibili01 前后端分离介绍是Web应用开发-后端基础-基于Springboot框架的第1集视频&#xff0c;该合集共计29集&#xff0c;视频收藏或关注UP主&#xff0c;及时了解更多相关视频内容。https://w…

信息安全工程师(39)防火墙防御体系结构类型

前言 防火墙防御体系结构类型多样化&#xff0c;每种类型都针对不同的安全需求和应用场景&#xff0c;提供不同层次的保护。 一、传统防火墙系统 包过滤防火墙 原理&#xff1a;通过检查进出网络数据包的头信息&#xff08;如源IP地址、目的IP地址、源端口、目的端口和协议等&a…

用langchain+streamlit应用RAG实现个人知识库助手搭建

RAG原理概述 RAG&#xff08;Retrieval-Augmented Generation&#xff09; 是一种结合了信息检索和生成式人工智能技术的模型架构&#xff0c;旨在让模型生成更有根据和更准确的回答。通俗来讲&#xff0c;它让模型不只是凭借自己的“记忆”&#xff08;预训练数据&#xff09…

Python | Leetcode Python题解之第456题132模式

题目&#xff1a; 题解&#xff1a; class Solution:def find132pattern(self, nums: List[int]) -> bool:candidate_i, candidate_j [-nums[0]], [-nums[0]]for v in nums[1:]:idx_i bisect.bisect_right(candidate_i, -v)idx_j bisect.bisect_left(candidate_j, -v)if…

如何实现 C/C++ 与 Python 的通信?

在现代编程中&#xff0c;C/C与Python的通信已经成为一种趋势&#xff0c;尤其是在需要高性能和灵活性的场景中。本文将深入探讨如何实现这两者之间的互通&#xff0c;包括基础和高级方法&#xff0c;帮助大家在混合编程中游刃有余。 C/C 调用 Python&#xff08;基础篇&#…

APP自动化搭建与应用

APP自动化环境搭建 用于做APP端UI自动化&#xff0c;adb连接手机设备。 需要的工具java编辑器&#xff1a;jdk、Android-sdk软件开发工具组、appium的python客户端、nodes.js、夜神模拟器、apk包、uiautomatorviewer 第一步&#xff1a;安装sdk&#xff0c;里面包含建立工具bu…

QD1-P6 HTML常用标签:列表

本节视频 https://www.bilibili.com/video/BV1n64y1U7oj?p6 ‍ 本节学习HTML列表标签。HTML 列表有多种形式&#xff0c;最重要的有两种&#xff1a; 有序列表无序列表 一、有序列表 1.1 写法 <ol><li>首先</li><li>其次</li><li>最…

Shell入门基础学习笔记

目录 第1章 Shell概述 第2章 Shell解析器 第3章 Shell脚本入门 第4章 Shell中的变量 4.1 系统变量 4.2 自定义变量 4.3 特殊变量&#xff1a;$n 4.4 特殊变量&#xff1a;$# 4.5 特殊变量&#xff1a;$*、$ 4.6 特殊变量&#xff1a;$&#xff1f; 第5章 运算符 …

数据结构-4.5.KMP算法(旧版上)-朴素模式匹配算法的优化

朴素模式匹配算法最坏的情况&#xff1a; 一.实例&#xff1a; 第一轮匹配失败&#xff0c;开始下一轮的匹配&#xff1a; 不断的操作&#xff0c;最终匹配成功&#xff1a; 如上述图片所述&#xff0c;朴素模式匹配算法会导致时间开销增加&#xff0c; 优化思路&#xff1a;主…

Prometheus之Pushgateway使用

Pushgateway属于整个架构图的这一部分 The Pushgateway is an intermediary service which allows you to push metrics from jobs which cannot be scraped. The Prometheus Pushgateway exists to allow ephemeral and batch jobs to expose their metrics to Prometheus. S…

手撕数据结构 —— 顺序表(C语言讲解)

目录 1.顺序表简介 什么是顺序表 顺序表的分类 2.顺序表的实现 SeqList.h中接口总览 具体实现 顺序表的定义 顺序表的初始化 顺序表的销毁 打印顺序表 ​编辑 检查顺序表的容量 尾插 尾删 ​编辑 头插 头删 查找 在pos位置插入元素 删除pos位置的值 ​…

【JavaEE】【多线程】Thread类讲解

目录 Thread构造方法Thread 的常见属性创建一个线程获取当前线程引用终止一个线程使用标志位使用自带的标志位 等待一个线程线程休眠线程状态线程安全线程不安全原因总结解决由先前线程不安全问题例子 Thread构造方法 方法说明Thread()创建线程对象Thread(Runnable target)使用…

初始Redis

Mysql最大的问题在于,访问速度比较慢 而Redis是内存中存储数据的中间件,可以作为数据库使用,比较快,和Mysql相比,存储空间有限 Redis是在分布式系统中,才能发挥威力的,在单机程序,直接通过变量存储数据的方式,是比使用redis更优的选择 那么要求更大更快,就可以把redis和mysq…

修改银河麒麟操作系统V10(SP1)网卡名称为ethx

修改银河麒麟桌面操作系统V10&#xff08;SP1&#xff09;网卡名称为ethx 步骤一&#xff1a;查看当前网卡信息步骤二&#xff1a;修改GRUB配置文件步骤三&#xff1a;更新GRUB配置步骤四&#xff1a;编辑网络接口文件步骤五&#xff1a;重启机器 &#x1f496;The Begin&#…

【Kubernetes】常见面试题汇总(五十五)

目录 121. POD 创建失败&#xff1f; 122. POD 的 ready 状态未进入&#xff1f; 特别说明&#xff1a; 题目 1-68 属于【Kubernetes】的常规概念题&#xff0c;即 “ 汇总&#xff08;一&#xff09;~&#xff08;二十二&#xff09;” 。 题目 69-113 属于【Kube…

数据结构-排序1

1.排序的概念 排序&#xff1a;所谓排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递增或递减的排列起来的操作。 稳定性&#xff1a;假定在待排序的记录序列中&#xff0c;存在多个具有相同的关键字的记录&#xff0c;若经过排序…

【项目安全设计】软件系统安全设计规范和标准(doc原件)

1.1安全建设原则 1.2 安全管理体系 1.3 安全管理规范 1.4 数据安全保障措施 1.4.1 数据库安全保障 1.4.2 操作系统安全保障 1.4.3 病毒防治 1.5安全保障措施 1.5.1实名认证保障 1.5.2 接口安全保障 1.5.3 加密传输保障 1.5.4终端安全保障 资料获取&#xff1a;私信或者进主页。…

『网络游戏』窗口基类【06】

创建脚本&#xff1a;WindowRoot.cs 编写脚本&#xff1a; 修改脚本&#xff1a;LoginWnd.cs 修改脚本&#xff1a;LoadingWnd.cs 修改脚本&#xff1a;ResSvc.cs 修改脚本&#xff1a;LoginSys.cs 运行项目 - 功能不变 本章结束

【数据管理】DAMA-元数据专题

导读&#xff1a;元数据是关于数据的组织、数据域及其关系的信息&#xff0c;是描述数据的数据。在数据治理中&#xff0c;元数据扮演着至关重要的角色&#xff0c;是数据治理的基础和支撑。以下是对数据治理中元数据专题方案的详细介绍&#xff1a; 目录 一、元数据的重要性 …

Qt教程(001):Qt概述与安装

文章目录 一、Qt概述1.1 什么是Qt1.2 Qt优点1.3 Qt发展史1.4 支持的平台1.5 成功案例1.6 下载安装1.7 QtCreator介绍 一、Qt概述 1.1 什么是Qt Qt是一个跨平台的C图形用户界面应用程序框架。它为应用程序开发者提供建立艺术级图形界面所需的所有功能。它是完全面向对象的&…