简体   繁体   English

dijkstra算法在基于堆的优先级队列中的查找时间

[英]lookup time in heap based priority queue for dijkstra algorithm

I want to use priority_queue as vertex container for a dikjstra algorithm, after calling extractMin to get a vertex u , I find all adjacent vertex v , and then I might call decreaseKey for v , I known that the decreaseKey spend O(lgN) time, however, before calling decreaseKey , I have to first find the position of v . 我想用priority_queue作为顶点容器的dikjstra算法,打完电话后extractMin得到一个顶点u ,我发现所有相邻顶点v ,然后我可能会叫decreaseKeyv ,我知道, decreaseKey支出O(LGN)的时间,但是,在调用decreaseKey之前,我必须首先找到v的位置。

I used std::vector and std::make_heap/std::push_heap/std::pop_heap to maintain the priority_queue, using this data structure, to find a specific data would spend O(N) time, which would make the O(lgN) decreaseKey meaningless. 我使用此数据结构使用std::vectorstd::make_heap/std::push_heap/std::pop_heap来维护priority_queue,以查找特定数据将花费O(N)时间,这将使O( LGN) decreaseKey意义。

So, what is the common method for the vertex container in dikjstra algorithm, or should I add a member in class Vertex to keep its position in the heap? 那么,dikjstra算法中顶点容器的常用方法是什么,还是应该在class Vertex添加一个成员以保持其在堆中的位置?

First of all you do not need to use std::***_heap functions; 首先,您不需要使用std::***_heap函数; There already is priority_queue in STL. STL中已经有priority_queue

As for updating values already in the heap, you may insert pair s of index and distance. 作为用于在堆已更新的值,可能会插入pair索引和距离的第 And maintain a distance vector to verify if the distance is still valid or has got updated; 并保持距离矢量以验证距离是否仍然有效或已更新; something like: 就像是:

typedef struct {
    size_t index;   /* index of vertex and the distance at which */
    int dist;       /* the vertex was pushed to the heap         */
} value_t;

/* `a` has less priority than `b` if it is further away */
const auto comp = [](const value_t & a, const value_t & b){
    return b.dist < a.dist;
};

priority_queue<value_t, vector<value_t>, decltype(comp)> heap(comp);

/* the *most current* shortest distances for all nodes */
vector<int> dist(n, inf); 

Then the Dikjstra loop would be something like: 然后,Dikjstra循环将类似于:

while(!heap.empty()) {
    const auto top = heap.top();
    heap.pop();

    if(dist[top.index] < top.dist) {
          /* the node has already been added at a  */
          /* shorter distance therefore skip it    */
          continue;
    }
    /* process the node & its neighbors */
    /* push to the heap neighbors which get their `dist` deccreased */
}

It is true that there may be multiple copies of a same node in the heap (at different distances where only one of them is still valid); 确实,堆中可能有同一节点的多个副本(在不同距离处,其中只有一个仍然有效); but you may show that the size of the heap is O(num. of edges) , therfore the heap would still perform O(log num. of nodes) . 但您可能会证明堆的大小为O(num. of edges) ,因此堆仍将执行O(log num. of nodes)

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

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