当前位置: 首页 > java >正文

6.4.2_2最短路径算法-Dijkstra算法

迪杰斯特拉

膜拜大佬大佬大佬大佬。。。。。。。。。

BFS算法的局限性:

BFS算法求最小路径长度不适用于带权值的图,如下图中的从G港出发根据BFS算法会计算R城的路径长度为10和P城的路径长度为5,但是实际G港->P城->R城距离为7这才是最短路径

带权路径长度(简称为路径长度):一条路径上的所有边的权值之和

 

Dijkstra算法:

从单源顶点V0开始,以有向图为例

过程:

初始化:初始化三个数组,final[]数组用来记录单源顶点到各顶点是否找到了最短路径,V0是起点,所以开始final[V0]=true,d其他顶点final值都设为false。dist[]数组表示目前能找到的最短路径长度,设置能从图上显而易见的最短路径长度。V0->V0最短路径长度为0,dist[0]=0,V0->V1,根据图V0和V1直接相连且权值为10,即初始化的时候dist[V1]=10,V0到V2没有直接相连的边,所以目前V0到V2没有最短路径,即dist[V2]=∞,V0到V3同dist[V3]=∞,V0到V4直接相连的边的权值为5即目前V0单源到V4最短路径为dist[4]=5,path[]数组用来记录每个顶点在最短路径上的直接前驱,设置从图上能显而易见得到的最短路径的直接前驱。path[0]=-1。开始已经知道V0->V1即目前能找到的一条路是从V0过来的,所以path[1]=0表示目前能找到的最短的一条路径是从V0->V1,V4同目前能确定的一条比较好的路径也是从V0>V4,即path[4]=0

第一轮:找final中值为false的即还没找到最短路径的节点+dist中最短路径长度最小的顶点(就是找final中值为false的且dist中数值最小的,把这个顶点的final设为true就行了),明显是V4(V1-V4都没确定最端路径长度,V1-V4dist最小的值为5,即dist[4]=5)然后把final[4]=true表示顶点4已找到最短路径且4的直接前驱是V0即path[4]=0,然后修改其他没有确定最短路径长度的顶点的dist和path值,没加入V4前V0->V1路径长度为10且path[1]=0,加入了V4之后有V0->V4->V1即5+3=8,10>8即V0到V4的最短路径为8,最短路径中V1的直接前驱为V4,即修改dis[1]=8,path[1]=4,同理修改V0->V2的dist和path,加入V4后有V0->V4->V2即5+9=14即修改dist[2]=14,path[2]=4,V0->V4->V3即5+2=7,dist[3]=7,path[3]=4

第2轮:找final中值为false的且dist中数值最小的顶点,把这个顶点的final,明显是V3(V1-V3都没确定最端路径长度,V1-V3dist最小的值为7,即dist[3]=7)然后把final[3]=true表示顶点3已找到最短路径且3的直接前驱是V0即path[3]=4,然后修改其他没有确定最短路径长度的顶点的dist和path值即修改V1和V2,没加入V3前V0->V4->V2最短路径长度为14,加入了V3之后有V0->V4->V3->V2即5+2+6=13,13<14即V0到V2的最短路径为13,最短路径中V2的直接前驱为V3,即修改dis[2]=13,path[2]=3,V1没找到不用修改

第3轮:找final中值为false的且dist中数值最小的顶点,把这个顶点的final,明显是V1(V1-V2都没确定最端路径长度,V1-V2dist最小的值为8,即dist[1]=8)然后把final[1]=true表示顶点1已找到最短路径且1的直接前驱是V0即path[1]=4,然后修改其他没有确定最短路径长度的顶点的dist和path值即修改V2,没加入V1前V0->V4->V3->V2最短路径长度为13,加入了V1之后有V0->V4->V1->V2即5+3+1=9,9<13即V0到V2的最短路径为9,最短路径中V2的直接前驱为V1,即修改dis[2]=9,path[2]=1

第3轮:找final中值为false的且dist中数值最小的顶点,把这个顶点的final,明显是V2(就剩下V2了)然后把final[2]=true表示顶点2已找到最短路径且2的直接前驱是V1即path[2]=1,然后修改其他没有确定最短路径长度的顶点的dist和path值发现final数组值都为true都确定了结束

找V2顶点最短路径长度+路径顶点序列:

最短路径长度看dist,dist[2]=9即V2最短路径长度为9

最短路径长度顶点序列看path,即从当前顶点找直接前驱直到找到path值为单源的这一串序列即为最短路径长度序列,path[2]=1即直接前驱为V1,path[1]=4即V1直接前驱为V4,path[4]=0即V4直接前驱为V0结束(因为单源节点是V0),再左朝向即可如下:

V2 ← V1← V4← V0

 

Dijkstra算法时间复杂度:

 和普利姆算法相似,时间复杂度都是O(v²)(考试不考理解吧,背过就行了吧。。。。。。。)

 用于负权值带权图:

迪杰斯特拉算法用于带负值的带权图求最小路径时可能失效

如下所示:从V0出发,根据迪杰斯特拉算法,开始final中V1和V2值为false且dist[2]长度最小于是先确定V2的最小路径长度,设置final[2]=true,path[2]=0,dist[2]=7,再修改没确定最短长度的V1,改不了目前10就是V1的最短路径长度,于是确定V1,设置final[1]=true,path[1]=0,dist[1]=10然后没有可确定的顶点了算法结束,但是实际上V0->V2的最短长度应为V0->V1->V2即10-5=5,这个比目前迪杰斯特拉算法计算出的最短路径长度10要小,于是迪杰斯特拉算法失效

 

。。。。。。。。。。。。。。。 

http://www.xdnf.cn/news/8878.html

相关文章:

  • DAY34
  • Spring | 在Spring中使用@Resource注入List类型的Bean并按优先级排序
  • VMware+Windows 11 跳过安装阶段微软账号登录
  • TSO-DSO接口有功和无功灵活性区域估计
  • 需求管理工具使用不当,如何优化?
  • 今日は進展があまりありませんでした。悪名高いACM
  • RocketMQ 索引文件(IndexFile)详解:结构、原理与源码剖析
  • WebGL3(WebGL or WebGPU?)
  • QTableWidget的函数和信号介绍
  • Android7 Input(九)View 建立Input Pipeline
  • html学习
  • MySQL:索引
  • hugo博客搭建,github部署
  • 前缀和知识笔记
  • 差速器行星齿轮机械加工工艺及工序卡设计
  • Redis缓存异常问题深度解析:穿透、击穿与雪崩
  • 如何设计一个高性能的短链设计
  • ind_knn_ad环境搭建和运行【用自己的数据集】
  • 【Linux】系统程序−进度条
  • DAX权威指南3:变量、迭代函数与计算组
  • 【MySQL】第十一弹——JDBC编程
  • 如何用,向量表示3维空间种的有向线段(4,2,3)
  • 【电子通识】FPC连接器组成部分与不良案例术语
  • 常用正则表达式及语法详解
  • 【医学影像 AI】探索 MONAI:医学影像 AI 的综合框架
  • matlab实现SS-ELM和US-ELM
  • 计算机网络技术(二)
  • Linux多线程编程
  • 如何使用Webpack实现异步加载?
  • redis集群创建时手动指定主从关系的方法