最短路径-Dijkstra(迪杰斯特拉)算法

2024-03-08 12:48

本文主要是介绍最短路径-Dijkstra(迪杰斯特拉)算法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  • 最短路径-Dijkstra(迪杰斯特拉)算法


  • 网图的最短路:

最短路径,是指两顶点之间经过的边上权值之和最小的路径,并且我们称路径的第一个顶点是源点,最后一个顶点是终点

  • Dijkstra(迪杰斯特拉)算法:

概况:

按路径长度递增的次序产生的最短路径算法,通过一步步计算出路径之间顶点的最短路径,在此过程中都是基于已经求出的最短路径基础上,求得更远顶点的最短路径

思想:

当前已经求得的最短路径边集为{MT}当前最短路终点与相连点(不在MT中)的距离(与起点距离)集合为{WP}

每次都在WP中取与当前终点最近的一个点,将最短边L加入最短路径集{MT},记此时新的终点为NewEnd

扫描不在最短路径中的所有点,如果 NewEnd+L<Dis(表示起点到当前扫描点的距离),更新最短路

相似算法:

在最小生成树上用过类似思想,只不过最小生成树要求全部点都要连通

留个传送门:最小生成树-Prim(普里姆)算法

图解:

两个工具:

a.Path[MAX_SIZE]:记录路径,Path[i]是i的前驱,路径方向  Path[i] -> i

b.Short_Path[MAX_SIZE]:Short_Path[i] 表示 从起点Start(不一定是0或者1)到 i 的最短路径大小

以下图为栗,v0为起点

 

首先记录下v0到相连点的距离(明显是v1和v2),进行初始化,此时:

Path:{ 0 0 0 0 0 0 0 0 0 } --- 初始化0

Short_Path:{ 0 1 5 65535 65535 65535 65535 65535 65535 } --- v0与v1距离为1,v0与v2距离为5

选出最短Short_Path 中的最短距,v1成为新的最短路终点,如下图,此时v1与v2,v3,v4相连

所有v0-v3=1+7=8 .......,可得(扫描更新后):

Path:{ 0 0 1 1 1 0 0 0 0 } 

Short_Path:{ 0 1 4 8 6 65535 65535 65535 65535

 一样,选出Short_Path中此时没有加入最短路顶点的最短路(红色),也就是4,得到 v0-v1-v2 ,v2为最短路新顶点

继续更新最短路,加入v4,v5,很明显,v0-v1-v4=6,而v0-v2-v4=5,路径更新为后者

Path:{ 0 0 1 1 2 2 0 0 0 } 

Short_Path:{ 0 1 4 8 5 11 65535 65535 65535

此时没有加入最短路的最小路径为5,也就是v4作为新终点

按之前步骤继续往下走,直到v8:

Path:{ 0 0 1 4 2 4 3 6 7 } 

Short_Path:{ 0 1 4 7 5 8 10 12 16 } 

如下图,得到最短路径:v0-v1-v2-v4-v3-v6-v7-v8,最短路长度为16

 Short_Path的利用:

Short_Path 显然是每一次最短路径的延申,所以求得Start-End的最短路,同理,Start到任意点的最短路都可以在Short_Path 中查得

算法复杂度:

             O(n^2)

  • Dijkstra模板:

#include <iostream>
#include<memory.h>
using namespace std;
#define MAX_SIZE 1024
#define INF 65535//邻接图
struct MGrapth
{int Vexs[MAX_SIZE];  //顶点表int Arc[MAX_SIZE][MAX_SIZE];  //邻接矩阵int Num_Vertext,Num_Edges;  //顶点数,边数
};
MGrapth Map;int Path[MAX_SIZE];   /*表示路径 Path[i]->i*/
int Short_Path[MAX_SIZE]; /*Start->i 的最短路径和*/
bool Vis[MAX_SIZE];   /*当前最短路径结点true*/
int Res;  /*最短路*/void Init(int n,int m)
{Res=0;memset(Vis,0,sizeof(Vis));memset(Path,0,sizeof(Path));for(int i=0;i<=n;i++)for(int j=0;j<=m;j++)Map.Arc[i][j]=INF;Map.Num_Vertext=n;Map.Num_Edges=m;
}void Dijkstra(int Start)
{int v,w,k,Min;for(v=0;v<Map.Num_Vertext;v++)Short_Path[v]=Map.Arc[Start][v];  /*Start到相连结点的距离*/Short_Path[Start]=0;   /*Start->Start 的距离为0*/Vis[Start]=1;   /*Start为当前最短路径结点*/for(v=1;v<Map.Num_Vertext;v++){Min=INF;for(w=0;w<Map.Num_Vertext;w++){if(!Vis[w]&&Short_Path[w]<Min){k=w;Min=Short_Path[w];}}Vis[k]=true; /*找出最短路到散点的最小值,将该散点连入最短路*/for(w=0;w<Map.Num_Vertext;w++)  /*更新最短路*/{if(!Vis[w]&&Min+Map.Arc[k][w]<Short_Path[w])  /*图中某点到v0的距离比当前路短,更新*/{Short_Path[w]=Min+Map.Arc[k][w];Path[w]=k;}}}
}

 

这篇关于最短路径-Dijkstra(迪杰斯特拉)算法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/787133

相关文章

springboot+dubbo实现时间轮算法

《springboot+dubbo实现时间轮算法》时间轮是一种高效利用线程资源进行批量化调度的算法,本文主要介绍了springboot+dubbo实现时间轮算法,文中通过示例代码介绍的非常详细,对大家... 目录前言一、参数说明二、具体实现1、HashedwheelTimer2、createWheel3、n

SpringBoot实现MD5加盐算法的示例代码

《SpringBoot实现MD5加盐算法的示例代码》加盐算法是一种用于增强密码安全性的技术,本文主要介绍了SpringBoot实现MD5加盐算法的示例代码,文中通过示例代码介绍的非常详细,对大家的学习... 目录一、什么是加盐算法二、如何实现加盐算法2.1 加盐算法代码实现2.2 注册页面中进行密码加盐2.

Java时间轮调度算法的代码实现

《Java时间轮调度算法的代码实现》时间轮是一种高效的定时调度算法,主要用于管理延时任务或周期性任务,它通过一个环形数组(时间轮)和指针来实现,将大量定时任务分摊到固定的时间槽中,极大地降低了时间复杂... 目录1、简述2、时间轮的原理3. 时间轮的实现步骤3.1 定义时间槽3.2 定义时间轮3.3 使用时

Linux修改pip和conda缓存路径的几种方法

《Linux修改pip和conda缓存路径的几种方法》在Python生态中,pip和conda是两种常见的软件包管理工具,它们在安装、更新和卸载软件包时都会使用缓存来提高效率,适当地修改它们的缓存路径... 目录一、pip 和 conda 的缓存机制1. pip 的缓存机制默认缓存路径2. conda 的缓

Windows系统下如何查找JDK的安装路径

《Windows系统下如何查找JDK的安装路径》:本文主要介绍Windows系统下如何查找JDK的安装路径,文中介绍了三种方法,分别是通过命令行检查、使用verbose选项查找jre目录、以及查看... 目录一、确认是否安装了JDK二、查找路径三、另外一种方式如果很久之前安装了JDK,或者在别人的电脑上,想

Python中Windows和macOS文件路径格式不一致的解决方法

《Python中Windows和macOS文件路径格式不一致的解决方法》在Python中,Windows和macOS的文件路径字符串格式不一致主要体现在路径分隔符上,这种差异可能导致跨平台代码在处理文... 目录方法 1:使用 os.path 模块方法 2:使用 pathlib 模块(推荐)方法 3:统一使

一文教你解决Python不支持中文路径的问题

《一文教你解决Python不支持中文路径的问题》Python是一种广泛使用的高级编程语言,然而在处理包含中文字符的文件路径时,Python有时会表现出一些不友好的行为,下面小编就来为大家介绍一下具体的... 目录问题背景解决方案1. 设置正确的文件编码2. 使用pathlib模块3. 转换路径为Unicod

如何通过Golang的container/list实现LRU缓存算法

《如何通过Golang的container/list实现LRU缓存算法》文章介绍了Go语言中container/list包实现的双向链表,并探讨了如何使用链表实现LRU缓存,LRU缓存通过维护一个双向... 目录力扣:146. LRU 缓存主要结构 List 和 Element常用方法1. 初始化链表2.

MySQL9.0默认路径安装下重置root密码

《MySQL9.0默认路径安装下重置root密码》本文主要介绍了MySQL9.0默认路径安装下重置root密码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们... 目录问题描述环境描述解决方法正常模式下修改密码报错原因问题描述mysqlChina编程采用默认安装路径,

golang字符串匹配算法解读

《golang字符串匹配算法解读》文章介绍了字符串匹配算法的原理,特别是Knuth-Morris-Pratt(KMP)算法,该算法通过构建模式串的前缀表来减少匹配时的不必要的字符比较,从而提高效率,在... 目录简介KMP实现代码总结简介字符串匹配算法主要用于在一个较长的文本串中查找一个较短的字符串(称为