簡體   English   中英

dijkstra算法在基於堆的優先級隊列中的查找時間

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

我想用priority_queue作為頂點容器的dikjstra算法,打完電話后extractMin得到一個頂點u ,我發現所有相鄰頂點v ,然后我可能會叫decreaseKeyv ,我知道, decreaseKey支出O(LGN)的時間,但是,在調用decreaseKey之前,我必須首先找到v的位置。

我使用此數據結構使用std::vectorstd::make_heap/std::push_heap/std::pop_heap來維護priority_queue,以查找特定數據將花費O(N)時間,這將使O( LGN) decreaseKey意義。

那么,dikjstra算法中頂點容器的常用方法是什么,還是應該在class Vertex添加一個成員以保持其在堆中的位置?

首先,您不需要使用std::***_heap函數; STL中已經有priority_queue

作為用於在堆已更新的值,可能會插入pair索引和距離的第 並保持距離矢量以驗證距離是否仍然有效或已更新; 就像是:

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); 

然后,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 */
}

確實,堆中可能有同一節點的多個副本(在不同距離處,其中只有一個仍然有效); 但您可能會證明堆的大小為O(num. of edges) ,因此堆仍將執行O(log num. of nodes)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM