算法提升:图的Dijkstra(迪杰斯特拉)算法

news2024/11/28 20:58:11

目录

概念

思路

代码


概念

迪杰斯特拉算法(Dijkstra)是由荷兰计算机科学家狄克斯特拉于1959年提出的,因此又叫狄克斯特拉算法。是从一个顶点到其余各顶点的最短路径算法,解决的是有权图中最短路径问题。迪杰斯特拉算法主要特点是从起始点开始,采用贪心算法的策略,每次遍历到始点距离最近且未访问过的顶点的邻接节点,直到扩展到终点为止。

注意该算法要求图中不存在负权边,不然会导致算法被困在一个圈内。

思路

假设我们的目标是从A到D

基本的思路就是维护一个路径长度表,每个节点就是key本身,因为是从A节点出发到D节点,然后A的初始值就是0,其余值都是-1(表示还没有到)。

A

B

C

D

0

-1

-1

-1

然后开始从A往外找,找到所有的下游节点,我们发现可以是B、C、D,分别是2、8、6,这个时候就更新表:

A

B

C

D

0

2

8

6

然后A这个节点就被遍历过了,不需要再次遍历了,把A这个项close,从其余的所有项中找到最小值,然后以这个值为开始节点, 继续往下找,这里就是B节点。

B节点的下游是D,C,分别是1、4,但是因为从A出发时候到B,里面有了A到B的长度是2,所以A到D、C的长度就是3、6,我们发现比原来的值更小就更新表单,把B也close。

A

B

C

D

0

2

6

3

然后就发现现在距离最短的就是D,我们的目的地也是D,这个时候算法其实已经可以结束了。

简单总结一下就是:

  1. 从开始节点往下游找,更新维护一个open表,遍历完的节点进入close表;
  2. 从open表中找到不为-1,的最小值,作为新的开始节点找下游;
  3. 找到下游后要与之相比:
    1. 若下游节点OPEN表的值为-1,直接覆盖,并记录他的上游节点,为了之后追溯路径;
    2. 若下游节点OPNE表值不为-1,就把路径权值+开始节点的open表值与之相比,若比之较小便加入,并记录他的上游节点,为了之后追溯路径;
    3. 直到当前Open表中所有节点close,或open 表中最小的节点就是目标节点。

这也解释了为什么不可以在有负权,因为一旦有负数权重,就会导致之前的表单记录内容不再是“最小值”,尤其在带环的情况下,环最转,值越小,整个算法就会在环里自娱自乐。

代码

#include<iostream>
#include<string>
using namespace std;
class Node{
public:
	Node()
	{
		minL=100;//初始化最短路径为无穷大。
	}
	char node;//节点名称
	int minL;//当前节点的最短路径
	Node* last;//下一个节点
};//定义从一个节点类
 
void print(Node *node)//最短路径函数的递归打印
{
	if (node == NULL)
	{
		return;
	}
	print(node->last);/*递归调用,先打印前面的节点*/
    cout << node->node << "->";
}
 
int main()
{
 
	int wvalue[8][8];//定义路径权重	
for (int a = 0; a < 8; a++)
	{
		for (int b = 0; b < 8; b++)
		{
			wvalue[a][b] = 1000;//初始化权值,如若两个点没有连接则为无穷大。
		}
	}
    wvalue[0][1] = 2;//根据图来设置各个点之间的路径。
	wvalue[0][2] = 5;
	wvalue[0][3] = 4;
	wvalue[1][6] = 12;
	wvalue[1][2] = 2;
	wvalue[1][4] = 7;
	wvalue[2][3] = 1;
	wvalue[2][4] = 4;
	wvalue[2][5] = 3;
	wvalue[3][5] = 4;
	wvalue[4][5] = 1;
	wvalue[4][7] = 5;
	wvalue[5][7] = 7;
	wvalue[6][7] = 3;
	Node node[8];//定义节点变量
	node[0].node = 'O';//命名各个节点
	node[0].last = NULL;//初始化前一个节点为空
	node[1].node = 'A';
	node[2].node = 'B';
	node[3].node = 'C';
	node[4].node = 'D';
	node[5].node = 'E';
	node[6].node = 'F';
	node[7].node = 'T';
	Node u;//定义当前被访问的节点
	Node S[8];//辅助变量存储8个节点
    int a = 0;
	for (int i = 0; i < 8;i++) //第一个循环遍历这8个节点
{
		u = node[i];//当前被遍历的节点
		if (i==0)
		{
		 u.minL = 0;//初始化第一个结点的最短路径	
	    }
		S[i] = node[i];//储存被遍历的节点
		for (int j = 0;j<8; j++)//遍一个节点与其他8个节点的两个路径权值	
        {
			if (u.minL + wvalue[i][j] < node[j].minL)/*如果当前节点的最短路径加上该节点到相邻节点的权重小于其下一个节点路径的权重,则更新其下一个节点路径的最小距离*/	
        	{
				node[j].minL = u.minL + wvalue[i][j];
				node[j].last = &S[i];
 
			}
		}
}
	cout << node[7].minL << endl;//打印最短路径
	print(&node[7]);
	return 0;
}

 

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

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

相关文章

【Hack The Box】linux练习-- Ophiuchi

HTB 学习笔记 【Hack The Box】linux练习-- Ophiuchi &#x1f525;系列专栏&#xff1a;Hack The Box &#x1f389;欢迎关注&#x1f50e;点赞&#x1f44d;收藏⭐️留言&#x1f4dd; &#x1f4c6;首发时间&#xff1a;&#x1f334;2022年11月27日&#x1f334; &#x1…

MySQL的执行计划explain

select_type&#xff1a;表示的查询类型 SIMPLE&#xff1a;表示查询语句不包含子查询和union;PRIMARY&#xff1a;表示此查询是最外层的查询&#xff1b;UNION: 表示此查询是UNION的第二个或后续的查询&#xff1b;DEPENDENT UNION&#xff1a;表示此查询是UNION的第二个或后续…

ARM Developer Keil MDK 5.X Crack

ARM Developer Keil MDK是面向各种STM32微控制器产品的全面软件开发解决方案&#xff0c;提供创建、编译和调试嵌入式应用程序时所需的一切资源。MDK包括真正的Arm编译器和易于使用的Keil uVision IDE/调试器&#xff0c;可与STM32CubeMX和软件包连接。MDK还提供各种专业的中间…

Faster R-CNN详解

Faster R-CNN Faster R-CNN是作者Ross Girshick继Fast R-CNN后的又一力作。使用VGG16作为网络的backbone&#xff0c;推理速度在GPU上达到5fps(包括候选区域的生成)&#xff0c;准确率也有进一步的提升。在2015年的ILSVRC以及COCO竞赛中获得多个项目的第一名。 Faster R-CNN算…

Easyrecovery2022硬盘磁盘U盘免费数据恢复软件

EasyRcovery的软件支持因各种原因损坏或误删的文件&#xff0c;文档&#xff0c;照片&#xff0c;视频&#xff0c;音频&#xff0c;电子邮件等等类型的数据它都可以恢复。同时&#xff0c;这款软件不仅仅支持u盘的数据恢复&#xff0c;移动硬盘&#xff0c;磁盘&#xff0c;sd…

【POJ No. 3067】 公路交叉数 Japan

【POJ No. 3067】 公路交叉数 Japan 北大 OJ 题目地址 【题意】 东海岸有N 个城市&#xff0c;西海岸有M 个城市&#xff08;N ≤1000&#xff0c;M ≤1000&#xff09;&#xff0c;将建成K 条高速公路。每个海岸的城市从北到南编号为1, 2, ……每条高速公路都是直线&#xf…

计算机网络---TCP流量控制和拥塞控制

&#xff08;一&#xff09; TCP 流量控制 TCP提供流量控制服务来消除发送方&#xff08;发送速率太快&#xff09;使接收方缓存区溢出的可能性&#xff0c;因此 流量控制是一个速度匹配服务&#xff08;让发送方慢一点&#xff0c;要让接收方来得及接收&#xff0c;实现匹配发…

Qt编写物联网管理平台(支持win/linux/mac/嵌入式linux/modbus等)

一、前言 这个物联网综合管理平台前后迭代了五年&#xff0c;一点一滴慢慢积累起来&#xff0c;从最开始的只有modbus串口协议解析以及简单的表格显示数据&#xff0c;慢慢的逐渐增加了tcp_rtu支持&#xff0c;用户管理模块&#xff0c;地图监控模块&#xff0c;而后为了拓展性…

消息队列 RabbitMQ入门:Linux(Docker)中安装和卸载RabbitMQ服务

文章目录前言一、Linux中安装RabbitMQ下载Erlang下载RabbitMQ进入Linux进行安装启动RabbitMQ二、RabbitMQ Web管理页面安装RabbitMQ Web管理页面访问管理页面三、使用Docker安装RabbitMQ安装Docker安装启动RabbitMQ访问管理页面四、Linux卸载RabbitMQ相关卸载RabbitMQ卸载Erlan…

第41讲:MySQL内置的QL性能分析工具

文章目录1.SQL性能分析的概念2.分析数据库中SQL的执行频率3.数据库中的慢查询日志3.1.开启慢查询日志功能3.2.模拟慢SQL查询观察日志内容4.Profile查看SQL每个阶段的耗时4.1.开启Profile操作4.2.随便执行一些查询语句4.3.查询执行SQL的耗时4.4.查询某一条SQL每个阶段的耗时4.5.…

【ASM】字节码操作 工具类与常用类 InstructionAdapter 介绍

文章目录 1.概述1.1 为什么会有 InstructionAdapter类?2. InstructionAdapter2.1 class info2.2 fields2.3 构造方法2.4 methods3.示例3.1预期目标4.总结1.概述 在上一节:【ASM】字节码操作 工具类与常用类 AnalyzerAdapter 工作原理 我们学习了AnalyzerAdapter类的工作原理…

【OpenCV 例程 300篇】246. 特征检测之ORB算法

『youcans 的 OpenCV 例程300篇 - 总目录』 【youcans 的 OpenCV 例程 300篇】246. 特征检测之ORB算法 特征检测与匹配是计算机视觉的基本任务&#xff0c;包括检测、描述和匹配三个相互关联的步骤。广泛应用于目标检测、图像检索、视频跟踪和三维重建等诸多领域。 6.9.1 ORB 算…

【Hack The Box】linux练习-- SneakyMailer

HTB 学习笔记 【Hack The Box】linux练习-- SneakyMailer &#x1f525;系列专栏&#xff1a;Hack The Box &#x1f389;欢迎关注&#x1f50e;点赞&#x1f44d;收藏⭐️留言&#x1f4dd; &#x1f4c6;首发时间&#xff1a;&#x1f334;2022年11月23日&#x1f334; &…

函数调用在嵌入式架构设计中的应用

函数调用很好理解&#xff0c;即使刚学没多久的朋友也知道函数调用是怎么实现的&#xff0c;即调用一个已经封装好的函数&#xff0c;实现某个特定的功能。 把一个或者多个功能通过函数的方式封装起来&#xff0c;对外只提供一个简单的函数接口&#xff0c;然后在其他地方调用即…

SpringCloud - Config分布式配置中心

文章目录一.概述1. 分布式系统面临的配置问题2. 什么是配置中心3. 配置中心怎么用4. 配置中心能做什么二.Config服务端配置与测试1. 搭建1.1 在github上创建一个springcloud_config的新仓库1.2 获得新仓库的地址&#xff1a;1.3 本地硬盘目录上新建git仓库并clone1.4 创建文件1…

设置一个不能被继承的类

小屋杂谈&#xff0c;记录日常 方法1&#xff1a; 如果想让这个类不能被继承&#xff0c;可以把这个类的构造函数设置成私有&#xff0c;这样子类去继承他构造就会报错&#xff0c;这样的话这个类就是不能被继承的&#xff0c;如果需要用这个类的对象的话&#xff0c;在基类里…

机器学习中的交叉熵

文章目录一、背景二、概率论基础知识三、熵≈信息熵&#xff08;应用领域不同&#xff09;、相对熵KL散度、交叉熵、softmax、sigmoid、交叉熵损失图像分割如何理解CrossEntropyLoss()参考资料一、背景 学习机器学习过程中&#xff0c;总是会遇到交叉熵这个名词。通过交叉熵损…

SpringBoot整合knife4j

1.1 Swagger 前后端分离开发&#xff1a;前端和后端分开进行开发&#xff0c;2个项目&#xff0c;一个是前端项目&#xff0c;一个是后端项目 目前基本上很多小项目都是前后端分离&#xff0c;除了后台管理系统 前后端分离开发&#xff0c;前端(app、小程序、智能硬件等)怎么…

栈(C语言实现)

文章目录&#xff1a;1.栈的概念2.栈的结构3.接口实现3.1初始化栈3.2判断栈是否为空3.3压栈&#xff08;入栈&#xff09;3.4出栈3.5查看栈顶元素3.6统计栈内元素个数3.7销毁栈1.栈的概念 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操…

Credly 数字证书

Credly 数字证书 Credly 简介 通过 Credly 颁发的徽章是对学习成果、经验或能力的数字表述。Credly 数字证书包括常见的组织徽章&#xff0c;如&#xff1a;AWS, Adobe, Autodesk, Certiport, Microsoft, CISCO, IBM 等等&#xff0c;以一种简单和安全的方式在线分享和验证&a…