简体   繁体   English

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

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

Let's say i have a directed graph G(V,E) with integral positive weights on it's edges.If i know that for every edge e ∈ E weight(e) ∈ {0,1,..2^W}(where W is relatively small) how can i implement 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的算法?

I tried modifying Dial's algorithm where if weight(e) ∈ {0,1,..,W} i could use buckets and implement dijsktra in O(V*W+E) but i can't seem to have good results. 我尝试修改Dial的算法,如果weight(e)∈{0,1,..,W},我可以使用存储桶并在O(V * W + E)中实现dijsktra,但是我似乎无法获得良好的结果。

When I have to implement Dijkstra's algorithm, I usually do it using a binary heap without a decrease_key operation. 当我必须实现Dijkstra的算法时,我通常使用二进制堆来执行它, 而没有 reduce_key操作。

To do that, you put (cost,vertex) records in the heap, and whenever the cost for a vertex goes down, you just put in a new one. 为此,您将(成本,顶点)记录放入堆中,并且每当一个顶点的成本下降时,您只需放入一个新的记录即可。 When you pop a vertex out of the heap, then, just ignore it if it's already done. 当您从堆中弹出一个顶点时,如果已经完成,则可以忽略它。 You have to keep track of which vertexes are done anyway, so that is easy. 无论如何,您都必须跟踪完成了哪些顶点,这很容易。

This takes a bit more space, but the complexity remains O(|E| log V) (which is the same as O(|V+E| log |V|) or O(|E| log |E|) for the connected component that the algorithm will traverse ) 这会占用更多的空间,但是复杂度仍然为O(| E | log V)(与O(| V + E | log | V |相同)或O(| E | log | E |算法将遍历的连接组件)

Now the factor of log|E| 现在的log | E |的因子 above derives from the fact that there are up to |E| 上面的事实来自于| E | elements in the heap. 堆中的元素。 If you group all elements with the same priority into lists and put those lists in the priority queue, then the that log |E| 如果将具有相同优先级的所有元素分组到列表中并将这些列表放入优先级队列,则该日志| E | factor turns into log(number of distinct priorities). 因素变成对数(不同优先级的数量)。 Note that a heap array ceases to be an appropriate structure for the priority queue, but various kinds of ordered trees work fine. 注意,堆数组不再是优先级队列的合适结构,但是各种有序树都可以正常工作。 It's easy when you don't need decrease_key. 当您不需要reduce_key时,这很容易。

In your case, the difference in cost between vertexes at the front of the priority queue, and the highest cost in the priority queue is at most 2^W. 在您的情况下,优先级队列前面的顶点之间的成本差异与优先级队列中最高的成本之间的差异最大为2 ^ W。 That implies that there are at most 2^W distinct priorities in the queue and the complexity of Dijkstra's algorithm using this kind of priority queue is O(|E|W). 这意味着队列中最多有2 ^ W个不同的优先级,使用这种优先级队列的Dijkstra算法的复杂度为O(| E | W)。

Since you don't want to allocate 2^W buckets, a Patricia tree of linked lists would make a viable priority queue for your case. 由于您不想分配2 ^ W个存储桶,因此链表的Patricia树将为您的案例提供一个可行的优先级队列。

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

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