数据结构 —— Dijkstra算法

数据结构 —— Dijkstra算法

  • Dijkstra算法
  • 划分集合
  • 模拟过程
  • 打印路径

在上次的博客中,我们解决了使用最小的边让各个顶点连通(最小生成树
在这里插入图片描述这次我们要解决的问题是现在有一个图,我们要找到一条路,使得从一个顶点到另一个顶点路径权值之和最小(比如:找到从小潮到胖迪最短的一条路径):
在这里插入图片描述
我们可以看出来,小潮->小傲->胖迪这条路径是最短的。
在这里插入图片描述
而我们今天学的算法,Dijkstra,就是完成这样的工作的:

Dijkstra算法

Dijkstra算法是一种用于寻找图中两个节点之间的最短路径的算法,由荷兰计算机科学家Edsger W. Dijkstra于1956年发明。该算法的基本思想是使用贪心策略,从起始节点开始,逐步扩展到距离它最近的未访问过的节点,直到目标节点被访问。

以下是Dijkstra算法的基本步骤:

  1. 初始化将起点到所有其他节点的距离设为无穷大(表示还未计算),除了起点到自身的距离为0。创建一个空的已访问节点集合和一个包含所有节点的未访问节点集合。
  1. 从未访问节点集合中选择距离起点最近的节点,将其标记为已访问,并更新其邻接节点的距离如果某个邻接节点的距离通过当前节点更短,则更新该邻接节点的距离
  1. 重复步骤2,直到找到目标节点或未访问节点集合为空。
  1. 如果找到了目标节点,则返回从起点到目标节点的最短路径;否则,说明起点和目标节点之间不存在路径。

需要注意的是,Dijkstra算法只适用于没有负权重边的图,因为负权重边会导致算法无法正确地确定最短路径。此外,Dijkstra算法的时间复杂度为O(ElogV),其中E表示边的数量,V表示节点的数量。在实际应用中,可以使用优先队列等数据结构来优化算法的时间复杂度。

我们将上面的图改造复杂一点,这样可以看出Dijkstra算法的高效:
在这里插入图片描述

void TestGraph2(){string a[] = {"海皇","高斯","小傲","小潮","胖迪","小杨","皖皖"};Graph<string, int,INT_MAX, false> g1(a, sizeof(a)/sizeof(a[0]));g1.AddEdge("小潮", "小傲", 30);g1.AddEdge("小潮", "高斯", 83);g1.AddEdge("小潮", "海皇", 34);g1.AddEdge("胖迪", "海皇", 78);g1.AddEdge("胖迪", "小傲", 76);g1.AddEdge("小杨", "皖皖", 54);g1.AddEdge("小杨", "高斯", 48);g1.AddEdge("高斯", "皖皖", 55);g1.AddEdge("胖迪", "高斯", 70);g1.AddEdge("小傲", "海皇", 3);g1.Print();cout << endl;}

在这里插入图片描述

划分集合

Dijkstra算法中,提到我们要划分集合一个是访问过的集合,一个是没有被访问过的集合,假设我们从小潮开始:
在这里插入图片描述
我们可以用一个bool的数组,访问过了的标记为true,没有为false。
在这里插入图片描述假设我们要从小潮到胖迪,我们要计算路径之和,我们还需要一个数组存放到各个顶点边的权值:

在这里插入图片描述同时,如果我们想打印路径出来,我们还要一个数组存放路径(这里有点像并查集里面的操作)
在这里插入图片描述

模拟过程

假设我们从小潮开始,各个数组情况如下:
在这里插入图片描述

现在,扫描跟小潮相连的边,最小的权值相关结点标记:
在这里插入图片描述

现在我们从小傲出发,发现海皇近,跳到海皇,发现总路径之和为33,比原来34小,故更新,并标记:

在这里插入图片描述
我们代码实现一下:

    void Dijkstra(const V& srci, vector<W>& dest, vector<int>& parentPath ){// 将源节点转换为其在顶点列表中的索引int srcIndex = FindSrci(srci);// 初始化parentPath向量,用于记录最短路径上的前驱节点,初始值为-1表示未访问parentPath.resize(_vertex.size(), -1);// 初始化dest向量,用于记录从源节点到每个节点的最小距离,初始值为最大权重MAX_Wdest.resize(_vertex.size(), MAX_W);// 给源节点赋值为0,表示从源节点到自身距离为0dest[srcIndex] = W();// 初始化一个布尔型向量,用于记录每个节点是否已被访问,初始值为falsevector<bool> isVisted;isVisted.resize(_vertex.size(), false);// 主循环,迭代次数为顶点数for (size_t i = 0; i < _vertex.size(); i++){// 初始化最小距离为最大权重MAX_WW min = MAX_W;size_t u = srcIndex;// 寻找未被访问且具有最小dest值的节点ufor (size_t j = 0; j < _vertex.size(); j++){if (isVisted[j] == false && dest[j] < min){min = dest[j];u = j;}}// 标记节点u为已访问isVisted[u] = true;// 对节点u的所有邻居进行松弛操作for (size_t i = 0; i < _vertex.size(); i++){// 只处理未被访问的邻居,并且存在从u到i的边(_matrix[u][i] != MAX_W)if (isVisted[i] == false && _matrix[u][i] != MAX_W&& dest[u] + _matrix[u][i] < dest[i]){// 更新从源节点到节点i的最小距离dest[i] = dest[u] + _matrix[u][i];// 更新节点i的前驱节点为uparentPath[i] = u;}}}}

在这里插入图片描述

打印路径

打印路径记得一点,最后我们要逆置一下:

    // 打印从源节点到所有其他节点的最短路径void PrintShortestPath(const V& src, const vector<W>& dist, const vector<int>& parentPath){// 将源节点转换为其在顶点列表中的索引size_t srcIndex = FindSrci(src);// 遍历所有顶点for (size_t i = 0; i < _vertex.size(); i++){// 跳过源节点本身if (i == srcIndex)continue;// 创建一个vector,用于存储从目标节点到源节点的路径vector<int> path;// 当前处理的节点初始化为目标节点size_t current = i;// 从目标节点出发,回溯到源节点,构建路径while (current != srcIndex){// 将当前节点添加到路径vector中path.push_back(current);// 将当前节点设置为其前驱节点,继续回溯current = parentPath[current];}// 最后将源节点添加到路径vector中path.push_back(srcIndex);// 翻转路径vector,使得路径顺序从源节点到目标节点reverse(path.begin(), path.end());// 输出路径和对应的最短距离for (auto node : path){// 输出路径中的每个节点cout << _vertex[node] << "->";}// 输出从源节点到目标节点的最短距离cout << dist[i] << endl;}}

在这里插入图片描述

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

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

相关文章

对比学习和多模态任务

1. 对比学习 对比学习&#xff08;Contrastive Learning&#xff09;是一种自监督学习的方法&#xff0c;旨在通过比较数据表示空间中的不同样本来学习有用的特征表示。其核心思想是通过最大化同类样本之间的相似性&#xff08;或降低它们之间的距离&#xff09;&#xff0c;同…

【Linux】网络新兵连

欢迎来到 破晓的历程的 博客 ⛺️不负时光&#xff0c;不负己✈️ 引言 在上一篇博客中&#xff0c;我们简单的介绍了一些Linux网络一些比较基本的概念。本篇博客我们将开始正式学习Linux网络套接字的内容&#xff0c;那么我们开始吧&#xff01; 1.网络中的地址管理 大家一…

GraphRAG——一个基于图的检索增强生成的开源项目【送源码】

GraphRAG 最近几天&#xff0c;微软团队开源了GraphRAG&#xff0c;这是一种基于图&#xff08;Graph&#xff09;的检索增强生成方法。 先说说RAG吧&#xff0c;检索增强生成&#xff0c;相当于是从一个给定好的知识库中进行检索&#xff0c;接入LLM模型&#xff0c;让模型生…

(十六)视图变换 正交投影 透视投影

视图变换 代码实验 #include <glad/glad.h>//glad必须在glfw头文件之前包含 #include <GLFW/glfw3.h> #include <iostream> #define STB_IMAGE_IMPLEMENTATION #include "stb_image.h"//GLM #include <glm/glm.hpp> #include <glm/gtc/m…

C++初探究(2)

引用 对于一个常量&#xff0c;想要将其进行引用&#xff0c;则使用普通的引用相当于权限扩大&#xff08;常量为只读&#xff0c;但此处的引用参数为可读可写&#xff09;&#xff0c;C编译器会报错. 例如&#xff1a; const int a 10;int& ra a;//权限放大&#xff0…

Python大数据分析——决策树和随机森林

Python大数据分析——决策树和随机森林 决策树决策树节点字段的选择信息熵条件熵信息增益信息增益率 基尼指数条件基尼指数基尼指数增益 决策树函数 随机森林函数 决策树 图中的决策树呈现自顶向下的生长过程&#xff0c;深色的椭圆表示树的根节点&#xff1b;浅色的椭圆表示树…

Java项目:基于SSM框架实现的农家乐信息管理平台含前后台【ssm+B/S架构+源码+数据库+答辩PPT+开题报告+毕业论文】

一、项目简介 本项目是一套基于SSM框架实现的农家乐信息管理平台 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调试&#xff0c;eclipse或者idea 确保可以运行&#xff01; 该系统功能完善、界面美观、操作简单、功…

招投标信息采集系统:让您的企业始终站在行业前沿

一、为何招投标信息如此关键&#xff1f; 在经济全球化的大背景下&#xff0c;招投标活动日益频繁&#xff0c;成为企业获取项目、拓展市场的主流方式之一。招投标信息采集&#xff0c;作为企业战略决策的前置环节&#xff0c;其重要性不言而喻。它不仅关乎企业能否第一时间发…

WPF 初识依赖属性

依赖属性的意义和作用 核心模块内存共享&#xff0c;节省空间数据绑定、样式、模板、动画。。。。如果没有依赖属性&#xff0c;这个框架就是一个控件框架 相当于Winform 依赖属性的基本定义 基本过程&#xff1a;声明、注册、包装 在需要写依赖属性的类中&#xff0c;继承…

快速将一个网址打包成一个exe可执行文件

一、电脑需要node环境 如果没有下面有安装教程&#xff1a; node.js安装及环境配置超详细教程【Windows系统安装包方式】 https://blog.csdn.net/weixin_44893902/article/details/121788104 我的版本是v16.13.1 二、安装nativefier 这是一个GitHub上的开源项目&#xff1a…

C 语言函数

1.0 函数的创建和使用 在C语言中&#xff0c;函数是一种封装了特定功能的代码块&#xff0c;可以被程序中的其他部分调用。函数可以接受输入参数&#xff0c;并且可以返回一个值。定义一个函数的基本语法如下 #define _CRT_SECURE_NO_WARNINGS #include "stdio.h" …

阿里云人工智能平台PAI部署开源大模型chatglm3之失败记录--update:最后成功了!

想学习怎么部署大模型&#xff0c;跟着网上的帖子部署了一个星期&#xff0c;然而没有成功。失败的经历也是经历&#xff0c;记在这里。 我一共创建了3个实例来部署chatglm3&#xff0c;每个实例都是基于V100创建的&#xff08;当时没有A10可选了&#xff09;&#xff0c;其显…

x86芯片定制,Ethercat芯片定制,IP服务,适用于运动控制,工业总线等软硬一体机

x86芯片定制&#xff0c;Ethercat芯片定制 X86平台 我们的研发工程师已经积累了非常丰富的主板、整机设计经验&#xff0c;对接您的产品规格场景需求&#xff0c;快速交付样机&#xff0c;包含主板、BOX整机、平板电脑、CPCI等形态产品。降本、长生命周期、快速交付、及时响应…

IEC62056标准体系简介-2.IEC62056标准体系及对象标识系统(OBIS)

1. IEC 62056标准体系 IEC 62056标准体系目前共包括六部分&#xff0c;见图1&#xff1a; 第61部分&#xff1a;对象标识系统第62部分&#xff1a;接口类第53部分&#xff1a;COSEM应用层第46部分&#xff1a;使用HDLC&#xff08;High Level Data Link Control&#xff09;协…

Linux多进程和多线程(八)多线程

多线程 线程定义线程与进程线程资源 线程相关命令 pidstat 命令 top 命令ps 命令常见的并发方案 1. 多进程模式2. 多线程模式 创建线程 1. pthread_create() 示例:创建一个线程 2. pthread_exit() 退出线程3. pthread_join() 等待线程结束 示例: 线程分离 创建多个线程 示例 1:…

前端面试题35(在iOS和Android平台上,实现WebSocket协议有哪些常见的库或框架?)

在iOS和Android平台上&#xff0c;实现WebSocket协议有许多成熟且被广泛使用的库和框架。下面是一些推荐的选项&#xff1a; iOS 平台 SocketRocket 简介&#xff1a;这是由Facebook开源的库&#xff0c;专门为iOS和Mac OS X设计&#xff0c;提供WebSocket连接的功能。它基于S…

Blender新手入门笔记收容所(一)

基础篇 基础操作 视角的控制 控制观察视角&#xff1a;鼠标中键平移视图&#xff1a;Shift鼠标中键缩放视图&#xff1a;滚动鼠标中键滚轮 选中物体后&#xff1a;移动物体快捷键G&#xff0c;移动后单击鼠标就会定下来。 进入移动状态后&#xff1a;按Y会沿着Y轴移动进入移动…

HW期间——应急响应

01HW中应急响应的流程 001应急响应所处位置&#xff08;应急处置组&#xff09; 监控研判组发现的一些安全时间提供给应急处置组&#xff0c;应急处置组通过上机取证把线索给到溯源反制组。但是溯源反制组可能已经没有了&#xff0c;有些单位有&#xff0c;有些单位取消了。有…

Python神经模型评估微分方程图算法

&#x1f3af;要点 &#x1f3af;神经网络映射关联图 | &#x1f3af;执行时间分析 | &#x1f3af;神经网络结构降维 | &#x1f3af;量化图结构边作用 | &#x1f3af;数学评估算法实现 &#x1f36a;语言内容分比 &#x1f347;Python随机梯度下降算法 随机梯度下降是梯度…

matlab仿真 通信信号和系统分析(下)

&#xff08;内容源自详解MATLAB&#xff0f;SIMULINK 通信系统建模与仿真 刘学勇编著第三章内容&#xff0c;有兴趣的读者请阅读原书&#xff09; 一、离散傅里叶变换 clear all n0:30;%信号的时间范围 xsin(0.2*n).*exp(-0.1*n); k0:30;%频率范围 N31; Wnkexp(-j*2*pi/N).…