求解单源最短路的Dijkstra算法

Dijkstra算法1,英文为Dijkstra’s algorithm,常被译为迪杰斯特拉算法。该算法由Edsger Wybe Dijkstra2在1956年发现。Dijkstra算法使用类似BFS的方法解决带权无负权图的单源最短路问题。

算法描述

解决单源最短路,便是需要求解图GG上某个源点ss到其它点vV{s}v\in V- \lbrace s \rbrace的权值和最小的路径,这里显然有两个重要求解目标——权值和、路径,这里我们先不考虑具体路径的求解。

解集dist初始化

Dijkstra算法在过程中动态维护解集distdist,其中dist[i]dist[i]为当前ss到编号为ii的点之间的最小权值和。显然在算法开始前,有
dist[s]=0dist[v]=dist[s]=0 \\ dist[v]=\infty

松弛

Dijkstra的基础操作是松弛。显然对于任意时刻,如果存在一条边w(u,v)w(u,v),使得当前dist[u]+weight[u][v]<dist[v]dist[u]+weight[u][v]<dist[v],则可利用该边,将之前的解路径path[v]path[v]优化为path[u]w(u,v)path[u]\rightarrow w(u,v)

贪心地进行松弛操作

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

由于初始时dist[s]dist[s]00最小,故第一轮中的松弛其实是将dist[v]dist[v]初始化为weight[s][v]weight[s][v],整个算法将进行nn轮松弛。也有说法将第一轮松弛作为初始化的一部分,认为n1n-1轮松弛即可得到结果。这是亟需辨析的点。

伪代码

《算法导论》给出了以下伪代码:
求解单源最短路的Dijkstra算法

求解单源单汇点

显然上述流程中,一旦对汇点tt的松弛完成,则意味着最终的dist[t]dist[t]已经求得,此时可以终止算法。但该操作并不会降低算法的渐进复杂度,因为该汇点可能在最后一个才被选中进行松弛。

未完


  1. Dijkstra算法(维基百科) ↩︎

  2. 艾兹赫尔·迪杰斯特拉(维基百科) ↩︎

相关文章:

  • 2022-01-04
  • 2021-08-24
  • 2021-11-14
  • 2021-08-05
  • 2021-08-14
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2021-08-11
  • 2022-12-23
  • 2022-12-23
  • 2021-08-05
  • 2021-10-11
  • 2020-01-23
  • 2021-11-15
相关资源
相似解决方案