最短路径——迪杰斯特拉算法

简介: 版权声明:本文为博主原创文章,转载请注明出处http://blog.csdn.net/u013132758。 https://blog.csdn.net/u013132758/article/details/52293788 前言好久没有更新过算法的博客了,这篇博客主要介绍我们算法中很著名的一个问题——最短路径问题及解决最短路径问题的经典算法之一迪杰斯特拉算法。
版权声明:本文为博主原创文章,转载请注明出处http://blog.csdn.net/u013132758。 https://blog.csdn.net/u013132758/article/details/52293788

前言

好久没有更新过算法的博客了,这篇博客主要介绍我们算法中很著名的一个问题——最短路径问题及解决最短路径问题的经典算法之一迪杰斯特拉算法。

最短路径问题

最短路径问题是图论研究中的一个经典算法问题,旨在寻找图(由结点和路径组成的)中两结点之间的最短路径。算法具体的形式包括:                         

  • 确定起点的最短路径问题 -即已知起始结点,求最短路径的问题。
  • 确定终点的最短路径问题 -与确定起点的问题相反,该问题是已知终结结点,求最短路径的问题。在无向图中该问题与确定起点的问题完全等同,在有向图中该问题等同于把所有路径方向反转的确定起点的问题。
  • 确定起点终点的最短路径问题 -即已知起点和终点,求两结点之间的最短路径。
  • 全局最短路径问题 -求图中所有的最短路径。
其实就是字面意思,一个带边值的图中从某一个顶点到另外一个顶点的最短路径。如下图所示:你能求出V0-V8的最短路径吗?

而解决最短路径问题最常见的算法就是迪杰斯特拉(Dijkstra)算法和弗洛伊德算法(Floyd)算法。

迪杰斯特拉(Dijkstra)算法

1.算法简介

Dijkstra算法是由E.W.Dijkstra于1959年提出,又叫迪杰斯特拉算法,它应用了贪心算法模式,是目前公认的最好的求解最短路径的方法。算法解决的是有向图中单个源点到其他顶点的最短路径问题,其主要特点是每次迭代时选择的下一个顶点是标记点之外距离源点最近的顶点。但由于dijkstra算法主要计算从源点到其他所有点的最短路径,所以算法的效率较低。

2.算法原理

1.首先,引入一个辅助向量D,它的每个分量 D
 [i]
表示当前所找到的从起始点
 v
(即源点
 v 
)到其它每个顶点
 vi
的长度。
例如,D[3] = 2表示从起始点到顶点3的路径相对最小长度为2。这里强调相对就是说在算法执行过程中D的值是在不断逼近最终结果但在过程中不一定就等于长度。
2.D的初始状态为:若从v 到vi   有弧(即从v  vi   存在连接边),则D[i]   为弧上的权值(即为从  v   到vi   的边的权值);否则置D[i]   为∞。 显然,长度为 D  [j]   = Min{ D |  vj   ∈V } 的路径就是从v   出发到顶点vj   的长度最短的一条路径,此路径为(v,vj   )。
3.那么,下一条长度次短的是哪一条呢?也就是找到从源点v 到下一个顶点的最短路径长度所对应的顶点,且这条最短路径长度仅次于从源点v   到顶点  vj   的最短路径长度。 假设该次短路径的终点是vk ,则可想而知,这条路径要么是(  v,vk   ),或者是(v,vj,vk   )。它的长度或者是从v 到vk   的弧上的权值,或者是D  [j]   加上从vj   到vk   的弧上的权值。
4.一般情况下,假设S为已求得的从源点v 出发的最短路径长度的顶点的集合,则可证明:下一条次最短路径(设其终点为x )要么是弧(v,x   ),或者是从源点     出发的中间只经过S中的顶点而最后到达顶点     的路径。 因此,下一条长度次短的的最短路径长度必是D[j] = Min{ D[i]   |vi   ∈V-S },其中D  [i]   要么是弧(  v,vi   )上的权值,或者是D  [k]   (  vk   ∈S)和弧(  vk   ,  vi   )上的权值之和。

3、算法实例

我们看下面这幅图 求从 a 到 j 的最短路径。

4、算法实现

#include<stdio.h>
#include<stdlib.h>
#define max 11000000000
inta[1000][1000];
intd[1000];//d表示某特定边距离
intp[1000];//p表示永久边距离
inti,j,k;
intm;//m代表边数
intn;//n代表点数
intmain()
{
scanf("%d%d",&n,&m);
intmin1;
intx,y,z;
for(i=1;i<=m;i++)
{
scanf("%d%d%d",&x,&y,&z);
a[x][y]=z;
a[y][x]=z;
}
for(i=1;i<=n;i++)
d[i]=max1;
d[1]=0;
for(i=1;i<=n;i++)
{
min1=max1;
for(j=1;j<=n;j++)
if(!p[j]&&d[j]<min1)
{
min1=d[j];
k=j;
}
p[k]=j;
for(j=1;j<=n;j++)
if(a[k][j]!=0&&!p[j]&&d[j]>d[k]+a[k][j])
d[j]=d[k]+a[k][j];
}
for(i=1;i<n;i++)
printf("%d->",p[i]);
printf("%d\n",p[n]);
return0;
}

5、性能分析

迪杰斯特拉算法的时间复杂度为O(n^2),空间复杂度为O(n^3)。正因为如此当图中点较多时,算法的效率会很低。于是就有了对迪杰斯特拉算法的优化,最常见的就是堆优化,后期将为大家介绍迪杰斯特拉算法的优化。

相关文章
|
3月前
|
机器学习/深度学习 编解码 算法
【机器人路径规划】基于迪杰斯特拉算法(Dijkstra)的机器人路径规划(Python代码实现)
【机器人路径规划】基于迪杰斯特拉算法(Dijkstra)的机器人路径规划(Python代码实现)
387 4
|
9月前
|
存储 负载均衡 算法
基于 C++ 语言的迪杰斯特拉算法在局域网计算机管理中的应用剖析
在局域网计算机管理中,迪杰斯特拉算法用于优化网络路径、分配资源和定位故障节点,确保高效稳定的网络环境。该算法通过计算最短路径,提升数据传输速率与稳定性,实现负载均衡并快速排除故障。C++代码示例展示了其在网络模拟中的应用,为企业信息化建设提供有力支持。
278 15
|
10月前
|
运维 监控 算法
监控局域网其他电脑:Go 语言迪杰斯特拉算法的高效应用
在信息化时代,监控局域网成为网络管理与安全防护的关键需求。本文探讨了迪杰斯特拉(Dijkstra)算法在监控局域网中的应用,通过计算最短路径优化数据传输和故障检测。文中提供了使用Go语言实现的代码例程,展示了如何高效地进行网络监控,确保局域网的稳定运行和数据安全。迪杰斯特拉算法能减少传输延迟和带宽消耗,及时发现并处理网络故障,适用于复杂网络环境下的管理和维护。
|
存储 人工智能 算法
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
这篇文章详细介绍了Dijkstra和Floyd算法,这两种算法分别用于解决单源和多源最短路径问题,并且提供了Java语言的实现代码。
876 3
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
|
8月前
|
运维 监控 算法
基于 Python 迪杰斯特拉算法的局域网计算机监控技术探究
信息技术高速演进的当下,局域网计算机监控对于保障企业网络安全、优化资源配置以及提升整体运行效能具有关键意义。通过实时监测网络状态、追踪计算机活动,企业得以及时察觉潜在风险并采取相应举措。在这一复杂的监控体系背后,数据结构与算法发挥着不可或缺的作用。本文将聚焦于迪杰斯特拉(Dijkstra)算法,深入探究其在局域网计算机监控中的应用,并借助 Python 代码示例予以详细阐释。
224 6
|
10月前
|
存储 算法 测试技术
【狂热算法篇】探秘图论之 Floyd 算法:解锁最短路径的神秘密码(通俗易懂版)
【狂热算法篇】探秘图论之 Floyd 算法:解锁最短路径的神秘密码(通俗易懂版)
|
10月前
|
算法 编译器 C++
【狂热算法篇】探秘图论之Dijkstra 算法:穿越图的迷宫的最短路径力量(通俗易懂版)
【狂热算法篇】探秘图论之Dijkstra 算法:穿越图的迷宫的最短路径力量(通俗易懂版)
|
2月前
|
机器学习/深度学习 算法 机器人
【水下图像增强融合算法】基于融合的水下图像与视频增强研究(Matlab代码实现)
【水下图像增强融合算法】基于融合的水下图像与视频增强研究(Matlab代码实现)
279 0
|
2月前
|
数据采集 分布式计算 并行计算
mRMR算法实现特征选择-MATLAB
mRMR算法实现特征选择-MATLAB
213 2
|
3月前
|
传感器 机器学习/深度学习 编解码
MATLAB|主动噪声和振动控制算法——对较大的次级路径变化具有鲁棒性
MATLAB|主动噪声和振动控制算法——对较大的次级路径变化具有鲁棒性
227 3

热门文章

最新文章