繁体   English   中英

O((V + E)* W)中的Dijsktra算法

[英]Dijsktra's algorithm in O((V+E)*W)

假设我有一个有向图G(V,E)在其边缘上具有积分正权重。如果我知道对于每个边缘e∈E weight(e)∈{0,1,.. 2 ^ W}(其中W相对较小)如何在O((V + E)* W)中实现dijsktra的算法?

我尝试修改Dial的算法,如果weight(e)∈{0,1,..,W},我可以使用存储桶并在O(V * W + E)中实现dijsktra,但是我似乎无法获得良好的结果。

当我必须实现Dijkstra的算法时,我通常使用二进制堆来执行它, 而没有 reduce_key操作。

为此,您将(成本,顶点)记录放入堆中,并且每当一个顶点的成本下降时,您只需放入一个新的记录即可。 当您从堆中弹出一个顶点时,如果已经完成,则可以忽略它。 无论如何,您都必须跟踪完成了哪些顶点,这很容易。

这会占用更多的空间,但是复杂度仍然为O(| E | log V)(与O(| V + E | log | V |相同)或O(| E | log | E |算法将遍历的连接组件)

现在的log | E |的因子 上面的事实来自于| E | 堆中的元素。 如果将具有相同优先级的所有元素分组到列表中并将这些列表放入优先级队列,则该日志| E | 因素变成对数(不同优先级的数量)。 注意,堆数组不再是优先级队列的合适结构,但是各种有序树都可以正常工作。 当您不需要reduce_key时,这很容易。

在您的情况下,优先级队列前面的顶点之间的成本差异与优先级队列中最高的成本之间的差异最大为2 ^ W。 这意味着队列中最多有2 ^ W个不同的优先级,使用这种优先级队列的Dijkstra算法的复杂度为O(| E | W)。

由于您不想分配2 ^ W个存储桶,因此链表的Patricia树将为您的案例提供一个可行的优先级队列。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM