戴克斯特拉算法

✍ dations ◷ 2025-05-20 01:03:12 #戴克斯特拉算法

戴克斯特拉算法(英语:Dijkstra's algorithm),又称迪杰斯特拉算法、Dijkstra算法,是由荷兰计算机科学家艾兹赫尔·戴克斯特拉在1956年发现的算法,并于3年后在期刊上发表。戴克斯特拉算法使用类似广度优先搜索的方法解决赋权图的单源最短路径问题。

该算法存在很多变体:戴克斯特拉的原始版本仅适用于找到两个顶点之间的最短路径,后来更常见的变体固定了一个顶点作为源结点然后找到该顶点到图中所有其它结点的最短路径,产生一个最短路径树。

该算法解决了图 G = V , E {displaystyle G=langle V,Erangle } 上带权的单源最短路径问题:196–206。具体来说,戴克斯特拉算法设置了一顶点集合 S {displaystyle S} ,在集合 S {displaystyle S} 中所有的顶点与源点 s {displaystyle s} 之间的最终最短路径权值均已确定。算法反复选择最短路径估计最小的点 u V S {displaystyle uin {V-S}} 并将 u {displaystyle u} 加入 S {displaystyle S} 中。该算法常用于路由算法或者作为其他图算法的一个子模块。举例来说,如果图中的顶点表示城市,而边上的权重表示城市间开车行经的距离,该算法可以用来找到两个城市之间的最短路径。

应当注意,绝大多数的戴克斯特拉算法不能有效处理带有负权边的图。

戴克斯特拉算法在计算机科学的人工智能等领域也被称为均一开销搜索,并被认为是最良优先搜索(英语:best-first search)的一个特例。

戴克斯特拉算法通过保留目前为止所找到的每个顶点 v V {displaystyle vin V} s {displaystyle s} v {displaystyle v} 的最短路径来工作。初始时,原点 s {displaystyle s} 的路径权重被赋为 0 (即原点的实际最短路径=0)。同时把所有其他顶点的路径长度设为无穷大,即表示我们不知道任何通向这些顶点的路径。当算法结束时, d {displaystyle d} 中存储的便是从 s {displaystyle s} v {displaystyle v} 的最短路径,或者如果路径不存在的话是无穷大。

松弛操作是戴克斯特拉算法的基础操作:如果存在一条从 u {displaystyle u} v {displaystyle v} 的边,那么从 s {displaystyle s} v {displaystyle v} 的一条新路径是将边 w ( u , v ) E {displaystyle w(u,v)in E} 添加到从 s {displaystyle s} u {displaystyle u} 的路径尾部来拓展一条从 s {displaystyle s} v {displaystyle v} 的路径。这条路径的长度是 d + w ( u , v ) {displaystyle d+w(u,v)} 。如果这个值比目前已知的 d {displaystyle d} 的值要小,那么可以用这个值来替代当前 d {displaystyle d} 中的值。松弛边的操作一直执行到所有的 d {displaystyle d} 都代表从 s {displaystyle s} v {displaystyle v} 的最短路径的长度值。

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

《算法导论》中给出了以下伪代码:该伪代码计算并保留图 G {displaystyle G} 中原点 s {displaystyle s} 到每一顶点 v {displaystyle v} 的最短距离 d {displaystyle d} 。其中,函数 E x t r a c t M i n ( Q ) {displaystyle Extract-Min(Q)} 将顶点集合 Q {displaystyle Q} 中有最小 d {displaystyle d} 值的顶点 u {displaystyle u} Q {displaystyle Q} 中删除并返回 u {displaystyle u}

 1  function Dijkstra(G, w, s) 2   INITIALIZE-SINGLE-SOURCE(G, s)                //实际上的操作是将每个除原点外的顶点的                    d                      {displaystyle d}  置为无穷大,                    d                =        0              {displaystyle d=0}   3                       S                              {displaystyle Sleftarrow emptyset }   4                       Q                s              {displaystyle Qleftarrow s}                                  //                    Q              {displaystyle Q}  是顶点                    V              {displaystyle V}  的一个优先队列,以顶点的最短路径估计排序 5   while(                    Q                              {displaystyle Qnot =emptyset }  ) 6       do                     u                E        X        T        R        A        C        T                M        I        N        (        Q        )              {displaystyle uleftarrow EXTRACT-MIN(Q)}            //选取                    u              {displaystyle u}                      Q              {displaystyle Q}  中最短路径估计最小的顶点 7                           S                S                u              {displaystyle Sleftarrow Scup u}   8       for each vertex v                             A        d        j                      {displaystyle in Adj}   9            do RELAX(u, v, w)            //松弛成功的结点会被加入到队列中

如果我们只对在 s {displaystyle s} t {displaystyle t} 之间查找一条最短路径的话,我们可以在第5或第6行添加条件如果满足 u = t {displaystyle u=t} 的话终止程序。

在肯尼·罗森所著的《离散数学及其应用》中给出了如下的另一份伪代码:

 1 procedure Dijkstra(G:边全为正权的图) 2   {G带有顶点                    a        =                  v                      0                          ,                  v                      1                          ,                  v                      2                          .        .        .              {displaystyle a=v_{0},v_{1},v_{2}...}  和若干边                    w        (                  v                      i                          ,                  v                      j                          )              {displaystyle w(v_{i},v_{j})}  } 3    for                     i        :=        1              {displaystyle i:=1}   to n 4                           D        (                  v                      i                          )        :=                      {displaystyle D(v_{i}):=infty }   5                        D        (        a        )        :=        0              {displaystyle D(a):=0}   6                        S        :=                      {displaystyle S:=emptyset }   7    while                     z                S              {displaystyle znotin S}   8    begin 9                              u        :=              {displaystyle u:=}  不属于                    S              {displaystyle S}                      D        (        u        )              {displaystyle D(u)}  最小的一个顶点 10                            S        :=        S                {        u        }              {displaystyle S:=Scup {u}}   11        for 所有不属于                    S              {displaystyle S}  的顶点                    v              {displaystyle v}   12            if                     D        (        u        )        +        w        (        u        ,        v        )        <        D        (        v        )              {displaystyle D(u)+w(u,v)<D(v)}   then                     D        (        v        )        :=        D        (        u        )        +        w        (        u        ,        v        )              {displaystyle D(v):=D(u)+w(u,v)}   13    end{                    D        (        z        )        =              {displaystyle D(z)=}  从a到z的最短路长度}

时间复杂度

我们可以用大O符号将该算法的运行时间表示为边数 | E | {displaystyle |E|} 和顶点数 | V | {displaystyle |V|} 的函数。

对于任何基于顶点集 Q {displaystyle Q} 的实现,算法的运行时间是 O ( | E | d k Q + | V | e m Q ) {displaystyle O(|E|cdot dk_{Q}+|V|cdot em_{Q})} ,其中 d k Q {displaystyle dk_{Q}} e m Q {displaystyle em_{Q}} 分别表示完成键的降序排列时间和从 Q {displaystyle Q} 中提取最小键值的时间。

对于没有任何优化的戴克斯特拉算法,实际上等价于每次遍历了整个图的所有结点来找到Q中满足条件的元素(即寻找最小的顶点是 O ( | V | ) {displaystyle O(|V|)} 的),此外实际上还需要遍历所有的边一遍,因此算法的复杂度是 O ( | V | 2 + | E | ) {displaystyle O(|V|^{2}+|E|)}

对于边数少于 | V | 2 {displaystyle |V|^{2}} 的稀疏图来说,可以用邻接表来更有效的实现该算法。

可以使用一个二叉堆或者斐波纳契堆用作优先队列来查找最小的顶点( E x t r a c t M i n {displaystyle Extract-Min} )以优化算法。当用到二叉堆的时候,算法所需的时间为 O ( ( | E | + | V | ) log | V | ) {displaystyle O((|E|+|V|)log |V|)} ,斐波纳契堆能提高一些性能,让算法运行时间达到 O ( | E | + | V | log | V | ) {displaystyle O(|E|+|V|log |V|)}

相关

  • 脑膜炎脑膜炎(英语:meningitis)指发生于脑膜的急性炎症,脑膜是包裹大脑和脊髓的保护薄膜。脑膜炎最常见的症状是发热、头痛和颈部僵硬。其他症状还包含精神错乱(英语:mental confusion)或
  • 孙是指子女的子女,男性称孙儿或孙子,女性称孙女。在父系社会,儿子的子女称为“内孙”或者“孙”,女儿的子女称为“外孙”。而自己的孙或外孙就称自己为祖父母或外祖父母。另外,闽
  • 两国关系科索沃与塞尔维亚之间关系长期以来处于紧张状况,原因在于科索沃宣布在2008年从塞尔维亚独立后,塞尔维亚强烈反对此举。最初不存在任何实体之间的关系,但随后的几年中已经有一些
  • 邦美蜀战役美国等国正式介入之后美国撤出至南越灭亡邦美蜀战役,(越南语:Trận Buôn Ma Thuột,英语:Battle of Ban Me Thuot)是越南战争后期的一场战斗,北越在1975年3月,越南人民军及越共对南
  • Ernesto Pompeo Molmenti医学博士莫尔门蒂医生(Ernesto Pompeo Molmenti)是一名美国移植外科医师 , 科学家, 和作者。 目前在纽约长岛执业。 他是 诺斯威尔健康集团北岸大学医院外科创新主任兼外科系
  • 惠主教惠主教(Channing Moore Williams,1829年7月18日-1910年12月2日),美国圣公会传教士,中国和日本主教。惠主教出生在里士满,1855年按立为会吏。1857年,他在中国按立为牧师,1857年被派往
  • 东尼泷谷《东尼泷谷》是一部改编自日本作家村上春树短篇作品的电影,由市川准执导,主要演员为尾形一成及宫泽理惠,旁白为西岛秀俊,配乐由著名日本音乐家坂本龙一负责。村上春树于1990年写
  • 韦恩·布里奇韦恩·布里奇(英语:Wayne Bridge,1980年8月5日-),已退役英格兰足球运动员,司职左后卫,为前英格兰足球代表队成员,曾效力英超南安普顿、富勒姆、切尔西、西汉姆联、桑德兰及曼城,于2013
  • 神秘博士敬献我儿托马斯《神秘博士敬献我儿托马斯》(英语:)是彼得·卡帕尔蒂录制并发给英格兰九岁自闭症男童托马斯·古多尔的短片,帮助孩子克服失去祖母的悲痛。视频全长42秒,卡帕尔蒂扮成英国广播公司科幻电视剧《神秘博士》中的第12任博士。信息对托马斯有积极影响,他的父亲罗斯·古多尔声称这是孩子得知祖母死讯后首度露出笑脸,并且终于鼓起勇气参加葬礼。2014年11月6日,罗斯把视频传至YouTube。他在事后接受媒体采访时表示此举只是想和家人分享,根本没想到视频会火。据有线电视新闻网报导,视频传至YouTube仅48小时后就有超过20
  • 延长 (日本)延长(923年5月29日-931年5月16日)是日本的年号。这平安时代之日本天皇是醍醐天皇、朱雀天皇。延长九年清凉殿雷击事件延长八年九月二十九日醍醐天皇