Dijkstra的算法修改

时间:2017-06-07 15:06:34

标签: algorithm graph-algorithm dijkstra

G (V, E)成为具有非负权重函数的加权有向图 对于某些非负整数W : E -> {0, 1, 2... W }W。如何修改Dijkstra的算法来计算O(V W + E)时间内给定源顶点的最短路径。

2 个答案:

答案 0 :(得分:2)

标准Dijkstra使用优先级队列并可以处理浮点值。这允许所有权重彼此不同并且意味着没有上限。

但是现在你有整数权重和上限:给定这些额外的约束,你应该能够构建一个更快的算法。实际上,您可以通过使用存储桶(每个权重一个)来存储节点。

完整:

  1. 创建标记为0, 1, 2, 3, ..., W(V-1)的存储桶,其中W是最大权重,V是节点数。存储区k将包含标有距离k的所有节点。每个存储桶都可以由向量或节点列表表示。
  2. 按顺序检查存储桶0, 1, 2, ..., WV,直到找到第一个非空存储桶。此存储桶中的节点位于边界。
  3. 此存储桶中的每个节点都标有其真实距离,然后从存储桶中删除。
  4. 现在重复步骤(2-4)(尽管在刚刚清空的桶中开始扫描2),直到所有桶都为空。
  5. 您需要WV个桶来说明W=1但图表是一行的退化情况。在这种情况下,最远的两个节点可以是W(V-1)

    可以获得更完整的解释here

答案 1 :(得分:1)

我曾经对此主题进行过研究,您正在寻找的算法是Dial algorithm。还有Dijkstra算法的进一步优化,所以我也在下面附上它。在最底层,我对这三种算法的性能进行了测试。

拨号算法

伪代码

enter image description here

小权重的有效算法。我们使用桶来代替优先级队列,每个权重从0到最大权重。复杂度为O(m+n*C),其中n为顶点数,C为最高费用,m为边数。

另一种方法是Radix algorithm

基数堆

伪代码

enter image description here

现在,我们有ln(C)个存储桶。 i存储桶存储范围[2^i, 2^(i+1)]中的边。复杂性变为O(m+nln(n*C))

测试

测试1

enter image description here

测试2

enter image description here

测试3

enter image description here

测试4

enter image description here