`

Dijkstra算法

阅读更多

Dijkstra算法是典型的最短路径算法,用于计算一个节点到其他所有节点的最短路径。主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。Dijkstra算法能得出最短路径的最优解,但由于它遍历计算的节点很多,所以效率低。

Dijkstra算法是很有代表性的最短路算法,在很多专业课程中都作为基本内容有详细的介绍,如数据结构,图论,运筹学等。

Dijkstra算法思想为:设G=(V,E)是一个带权有向图,把图中顶点集合V分成两组,第一组为已求出最短路径的顶点集合(用S表示,初始时S中只有一个源点,以后每求得一条最短路径,就将加入到集合S中,直到全部顶点都加入到S中,算法就结束了),第二组为其余未确定最短路径的顶点集合(用U表示),按最短路径长度的递增次序依次把第二组的顶点加入S中。在加入的过程中,总保持从源点v到S中各顶点的最短路径长度不大于从源点v到U中任何顶点的最短路径长度。此外,每个顶点对应一个距离,S中的顶点的距离就是从v到此顶点的最短路径长度,U中的顶点的距离,是从v到此顶点只包括S中的顶点为中间顶点的当前最短路径长度。

(1)初始时,S只包含源点,即S=,v的距离为0。U包含除v外的其他顶点,U中顶点u距离为边上的权(若v与u有边)或(若u不是v的出边邻接点)。

(2)从U中选取一个距离v最小的顶点k,把k,加入S中(该选定的距离就是v到k的最短路径长度)。

(3)以k为新考虑的中间点,修改U中各顶点的距离;若从源点v到顶点u(u U)的距离(经过顶点k)比原来距离(不经过顶点k)短,则修改顶点u的距离值,修改后的距离值的顶点k的距离加上边上的权。

(4)重复步骤(2)和(3),直到所有顶点都包含在S中。

 

Dijkstra算法是由荷兰计算机科学家艾兹格·迪科斯彻发现的。算法解决的是有向图中最短路径问题。

举例来说,如果图中的顶点表示城市,而边上的权重表示著城市间开车行经的距离。 Dijkstra算法可以用来找到两个城市之间的最短路径。

Dijkstra算法的输入包含了一个有权重的有向图G,以及G中的一个来源顶点S。 我们以V表示G中所有顶点的集合。图中的每一个边,都是两个顶点所形成的有序元素对。(u,v)表示从顶点uv有路径相连。 假设E为所有边的集合,而边的权重则由权重函数wE → [0, ∞]定义。 因此,w(u,v)就是从顶点u到顶点v的非负花费值(cost)。 边的花费可以想像成两个顶点之间的距离。任两点间路径的花费值,就是该路径上所有边的花费值总和。 已知有V中有顶点st,Dijkstra算法可以找到st的最低花费路径(i.e. 最短路径)。 这个算法也可以在一个图中,找到从一个顶点s到任何其他顶点的最短路径。


算法描述

  这个算法是通过为每个顶点v保留目前为止所找到的从s到v的最短路径来工作的。初始时,源点s的路径长度值被赋为0(d[s]=0), 同时把所有其他顶点的路径长度设为无穷大,即表示我们不知道任何通向这些顶点的路径(对于V中所有顶点vsd[v]= ∞)。当算法结束时,d[v]中储存的便是从sv的最短路径,或者是无穷大(如果路径不存在的话)。

   Dijstra算法的基础操作是边的拓展:如果存在一条从uv的边,那么从s到v的最短路径可以通过将边(u,v)添加到s到u的尾部来拓展。这条路径的长度是d[u]+w(u,v)。如果这个值比目前已知的d[v]的值要小,我们可以用新值来替代当前d[v]中的值。拓展边的操作一直执行到所有的d[v]都代表从s到v最短路径的花费。这个算法经过适当的组织因而当d[u]达到它最终的值的时候,每条边(u,v)都只被拓展一次。

算法维护两个顶点集S和Q。集合S保留了我们已知的所有d[v]的值已经是最短路径的值顶点,而集合Q则保留其他所有顶点。集合S初始状态为空,而 后每一步都有一个顶点从Q移动到S。这个被选择的顶点是Q中拥有最小的d[u]值的顶点。当一个顶点u从Q中转移到了S中,算法对每条外接边(u,v)进 行拓展。


算法思想

设S为最短距离已确定的顶点集(看作红点集),V-S是最短距离尚未确定的顶点集(看作蓝点集)。
①初始化
     初始化时,只有源点s的最短距离是已知的(SD(s)=0),故红点集S={s},蓝点集为空。
②重复以下工作,按路径长度递增次序产生各顶点最短路径
     在当前蓝点集中选择一个最短距离最小的蓝点来扩充红点集,以保证按路径权重递增的次序来产生各顶点的最短路径。
     当蓝点集中仅剩下最短距离为∞的蓝点,或者所有蓝点已扩充到红点集时,s到所有顶点的最短路径就求出来了。
  注意:
     ①若从源点到蓝点的路径不存在,则可假设该蓝点的最短路径是一条长度为无穷大的虚拟路径。
     ②从源点s到终点v的最短路径简称为v的最短路径;s到v的最短路径长度简称为v的最短距离,并记为SD(v)。
(3)在蓝点集中选择一个最短距离最小的蓝点k来扩充红点集
     根据按长度递增序产生最短路径的思想,当前最短距离最小的蓝点k的最短路径是:
     源点,红点1,红点2,…,红点n,蓝点k
 距离为:源点到红点n最短距离+<红点n,蓝点k>边长
     为求解方便,设置一个向量D[0..n-1],对于每个蓝点v∈ V-S,用D[v]记录从源点s到达v且除v外中间不经过任何蓝点(若有中间点,则必为红点)的"最短"路径长度(简称估计距离)。
     若k是蓝点集中估计距离最小的顶点,则k的估计距离就是最短距离,即若D[k]=min{D[i] i∈V-S},则D[k]=SD(k)。
     初始时,每个蓝点v的D[c]值应为权w<s,v>,且从s到v的路径上没有中间点,因为该路径仅含一条边<s,v>。
  注意:
     在蓝点集中选择一个最短距离最小的蓝点k来扩充红点集是Dijkstra算法的关键 

(4)k扩充红点集s后,蓝点集估计距离的修改

     将k扩充到红点后,剩余蓝点集的估计距离可能由于增加了新红点k而减小,此时必须调整相应蓝点的估计距离。
    对于任意的蓝点j,若k由蓝变红后使D[j]变小,则必定是由于存在一条从s到j且包含新红点k的更短路径:P=<s,…,k,j>。且D [j]减小的新路径P只可能是由于路径<s,…,k>和边<k,j>组成。
     所以,当length(P)=D[k]+w<k,j>小于D[j]时,应该用P的长度来修改D[j]的值。

(5)Dijkstra算法

 Dijkstra(G,D,s){
    //用Dijkstra算法求有向网G的源点s到各顶点的最短路径长度
    //以下是初始化操作
      S={s};D[s]=0; //设置初始的红点集及最短距离
      for( all i∈ V-S )do //对蓝点集中每个顶点i
          D[i]=G[s][i]; //设置i初始的估计距离为w<s,i>
       //以下是扩充红点集
      for(i=0;i<n-1;i++)do{//最多扩充n-1个蓝点到红点集
           D[k]=min{D[i]:all i V-S}; //在当前蓝点集中选估计距离最小的顶点k
           if(D[k]等于∞)
                return; //蓝点集中所有蓝点的估计距离均为∞时,
                     //表示这些顶点的最短路径不存在。
           S=S∪{k}; //将蓝点k涂红后扩充到红点集
           for( all j∈V-S )do //调整剩余蓝点的估计距离
               if(D[j]>D[k]+G[k][j])
                //新红点k使原D[j]值变小时,用新路径的长度修改D[j],
              //使j离s更近。
                   D[j]=D[k]+G[k][j];
          }
   }

 

 

 

分享到:
评论

相关推荐

    C语言实现Dijkstra算法

    Dijkstra算法,由荷兰计算机科学家艾兹格·迪科斯彻于1956年提出,是一种用于寻找图中两点间最短路径的算法。在C语言中实现Dijkstra算法,需要理解图的表示方法、优先队列的概念以及如何有效地更新路径信息。以下是...

    Dijkstra算法_C语言实现代码

    ### Dijkstra算法与C语言实现详解 #### 一、Dijkstra算法概述 Dijkstra算法是一种用于寻找图中两点间最短路径的经典算法,由荷兰计算机科学家Edsger W. Dijkstra于1956年提出,并在1959年的论文中正式发表。该算法...

    用Dijkstra算法求图中单源最短路径

    "用Dijkstra算法求图中单源最短路径" Dijkstra算法是一种常用的图搜索算法,用于解决单源最短路径问题。单源最短路径问题是指从一个出发顶点到所有可达顶点的最短路径问题。Dijkstra算法的原理是通过将图中的每个...

    Dijkstra算法Matlab实例代码实现

    Dijkstra算法算是贪⼼思想实现的,⾸先把起点到所有点的距离存下来找个最短的,然后松弛⼀次再找出最短的,所谓的松弛操作就是,遍历⼀遍看通过刚刚找到的距离最短的点作为中转站会不会更近,如果更近了就更新距离,...

    代码 基于最短路dijkstra算法离散优化问题代码

    代码 基于最短路dijkstra算法离散优化问题代码代码 基于最短路dijkstra算法离散优化问题代码代码 基于最短路dijkstra算法离散优化问题代码代码 基于最短路dijkstra算法离散优化问题代码代码 基于最短路dijkstra算法...

    Dijkstra算法的GUI界面设计

    Dijkstra算法是图论中的一个经典算法,由荷兰计算机科学家艾兹格·迪科斯彻在1956年提出,主要用于寻找有向或无向图中两个节点间的最短路径。在这个“Dijkstra算法的GUI界面设计”项目中,我们关注的是如何将这个...

    Dijkstra算法求解格栅地图路径matlab代码.rar

    Dijkstra算法是一种经典的最短路径搜索算法,由荷兰计算机科学家艾兹格·迪科斯彻在1956年提出。在计算机科学中,尤其是在图形算法、路由算法和网络流问题中,它被广泛用于寻找两个节点之间的最短路径。在本案例中,...

    Dijkstra算法应用举例

    "Dijkstra算法应用举例" Dijkstra算法是一种常用的图算法,用于寻找从起点到其他顶点的最短路径。下面是一个使用Dijkstra算法的应用举例,展示了如何使用该算法来解决实际问题。 从给定的代码中,我们可以看到,这...

    什么是dijkstra算法,Java和Python如何实现dijkstra算法

    dijkstra算法:什么是dijkstra算法,Java和Python如何实现dijkstra算法 dijkstra算法:什么是dijkstra算法,Java和Python如何实现dijkstra算法 dijkstra算法:什么是dijkstra算法,Java和Python如何实现dijkstra算法...

    最短路径--Dijkstra算法.ppt

    Dijkstra算法和图结构表示 Dijkstra算法是一种常用的图搜索算法,用于计算图中的一条最短路径。该算法的主要思想是从图的某个顶点出发,逐步扩展到其他顶点,直到找到目标顶点的最短路径。 在本节中,我们将详细...

    dijkstra算法C++实现的程序代码

    dijkstra算法C++实现的程序代码

    dijkstra算法解决最优路径规划问题_路径_dijkstra算法_

    除了基本版本,Dijkstra算法还有多种变体和优化方法,例如A*搜索算法,它结合了Dijkstra算法的全局最优性和启发式信息,提高了搜索效率。另外,Floyd-Warshall算法和Bellman-Ford算法也可用于求解最短路径问题,它们...

    基于Dijkstra算法的路径规划算法

    《基于Dijkstra算法的路径规划算法在MATLAB中的实现》 Dijkstra算法,由荷兰计算机科学家艾兹格·迪科斯彻提出,是一种用于解决单源最短路径问题的算法,广泛应用于网络路由、图形算法等领域。在本文中,我们将讨论...

    Dijkstra算法的应用

    ### Dijkstra算法的应用详解 #### 一、引言 Dijkstra算法是一种用于寻找加权图中两点间最短路径的经典算法。它不仅在计算机科学领域有着广泛的应用,而且在诸如交通规划、网络路由选择等领域也发挥着重要作用。...

    Dijkstra算法更新路由表

    "Dijkstra算法更新路由表" Dijkstra算法是一种常用的最短路径算法,广泛应用于计算机网络和交通网络等领域。该算法是由荷兰计算机科学家Edsger W. Dijkstra于1959年提出,目的是为了寻找图中的最短路径。 在计算机...

    Dijkstra算法寻找最短路径的完整源代码

    "Dijkstra算法寻找最短路径的完整源代码" 本资源提供了Dijkstra算法寻找最短路径的完整源代码,同时附带了Kruskal最小生成树算法。该程序提供了输入输出的完整控制台程序,能够帮助用户快速了解和应用Dijkstra算法...

    dijkstra算法的演示程序

    这个压缩包文件"**Dijkstra**"包含了一个Dijkstra算法的演示程序和源码,对于学习和理解该算法具有很高的价值。 首先,我们来深入理解Dijkstra算法的基本原理。算法的核心思想是采用贪心策略,每次选择当前未访问...

Global site tag (gtag.js) - Google Analytics