在elogv时间内实现dijkstra算法

时间:2014-06-17 05:36:37

标签: c++ algorithm

1) Create a Min Heap of size V where V is the number of vertices in the given graph. 
   Every node of min heap contains vertex number and distance value of the vertex.
2) Initialize Min Heap with source vertex as root (the distance value assigned to source
   vertex is 0). The distance value assigned to all other vertices is INF (infinite).
3) While Min Heap is not empty, do following
    a) Extract the vertex with minimum distance value node from Min Heap. Let the 
    extracted vertex be u.
    b) For every adjacent vertex v of u, check if v is in Min Heap. If v is in Min Heap
       and distance value is more than weight of u-v plus distance value of u, then 
       update the distance value of v.

我正在考虑在C ++中为Dijkstra实现这个伪代码。这是为了快速实施。我在这里有一些困惑,即我们使用堆来跟踪未探测区域的相邻顶点的Dijkstra得分。在3b中我们需要检查u的每个相邻顶点v,检查v是否为minHeap,minHeap是否在恒定时间内支持这样的操作,堆是搜索的最差数据结构,它应该花费线性时间来搜索它是否存在在min heap堆中,还是我们必须更新相邻的顶点,这样我们不仅应该知道它是否在minHeap中,而且它的位置也是如此,以便我们可以更新它,我们希望所有这些都在logv时间内发生,否则就有了没有快速实施的意义。 应该使用什么数据结构来代替Heap?

PS:我说的是一个实现,其中图形被实现为邻接列表。

1 个答案:

答案 0 :(得分:2)

在最坏的情况下,Dijkstra的算法必须执行|E| DecreaseKey操作和|V| ExtractMin操作。

  1. 在二进制堆数据结构中,DecreaseKey和ExtractMin操作的成本都是O(log(n))。因此,算法的总成本为O(|E|log(|V|) + |V|log(|V|))

  2. 如果我们使用fibonacci堆而不是简单的二进制堆,我们可以将总成本降低到O(|E| + |V|log(|V|)),因为现在DecreaseKey操作的摊余成本为O(1)

  3. 此外,对于图中的每个顶点,您必须维护指向堆的相应元素的指针数组。这样您就可以在O(1)

    中识别堆中的顶点