Dijkstra 算法示例

2024年8月28日 | 阅读 8 分钟

Djikstra算法的伪代码

每个顶点的路径距离都必须保留。这可以保存在一个v维数组中,其中v是顶点的总数。

我们不仅想知道最短路径有多长,还想找到它。为此,每个顶点都被映射到最近改变其路径长度的顶点。

当该过程完成时,我们可以通过从源顶点到目标顶点向后移动来发现路径。

可以使用最小优先级队列有效地接收最短路径距离的顶点。

Dijkstra算法源代码

以下是Dijkstra算法的C++实现。尽管抽象使代码更容易与算法连接,但代码的复杂性仍然可以增加。

输出

Distance from start: 4
f g d a
....................................
Process executed in 1.11 second
Press any key to continue.

说明

  • 该算法确定最短距离,但未确定路径信息。为了显示从源到多个顶点的最短路径,创建一个父数组,在更新距离时更新父数组(类似于prim方法),然后使用它。
  • Dijkstra函数也可用于有向图;代码适用于无向图。
  • 该程序计算源和每个顶点之间的最短路径。如果仅对源和单个目标之间的最短距离感兴趣,则当选择的最小距离顶点等于目标时,中断循环。
  • 该实现的**时间复杂度**为O(V2)。可以使用二叉堆将输入图的邻接表表示形式的大小减小到O(E * log V)。有关更多信息,请参阅Dijkstra算法的邻接表表示。
  • 对于具有不利权重周期的图,Dijkstra方法失败。对于带有负边的图,它可能会提供准确的答案,但您必须允许多次访问顶点,否则该版本将失去其快速的时间复杂度。Bellman-Ford方法可用于具有负权重边和周期的图;我们将在以后的文章中更详细地介绍此算法。

Dijkstra算法的复杂度

时间复杂度:O(E Log V) 其中,E是边的数量,V是顶点的数量。

空间复杂度:O(V)

Dijkstra算法示例

  • 确定最快路线
  • 在社交网络应用程序中
  • 在电话网络内
  • 在地图上定位地点

基于堆的Dijkstra最短路径算法,时间复杂度为O(E logV)

通常建议将堆(或优先级队列)用于Dijkstra算法,因为必要的运算(提取最小值和减小键)与堆(或优先级队列)的特性相对应。 priority_queue不支持decrease key,这是一个问题。为了解决这个问题,不要更新键,而是插入其额外的副本。因此,我们允许优先级队列包含同一顶点的多个实例。这种方法包含以下关键特征,并且不需要减少关键程序。

  • 每次顶点距离减小时,我们都会增加priority_queue中顶点实例的数量。即使有多个实例,我们也只考虑最接近我们的那个,而忽略其他实例。
  • 优先级队列中最多只有O(E)个顶点,并且O(logE)与O(logV)相同,因此时间复杂度保持在O(E * LogV)。

输出

Vertex Distance from Source
0          0
1          4
2          12
3          19
4          21
5          11
6          9
7          8
8          14
...............................
Process executed in 0.11 second
Press any key to continue.

时间复杂度:O(E * logV),其中E是边的数量,V是顶点的数量。

辅助空间:O(V)


下一主题欧几里德算法