Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implement decreaseKey in STL Priority Queue C++

I'm trying to implement Prim's Algorithm and for that I need to have a decreaseKey method for a priority queue (to update the key value in a priority queue). Can I implement this in the STL Priority Queue?

If it helps, this is the algorithm I'm following:

  • for each vertex u in graph G
    • set key of u to INFINITY
    • set parent of u to NIL
  • set key of source vertex to 0
  • en-queue to priority queue Q all vertices in graph with keys as above
  • while Q is not empty
    • pop vertex u with lowest key in Q
    • for each adjacent vertex v of u do
      • if (v is still in Q) and (key(u) + weight-function(u, v) < key(v)) then
        • set u to be parent of v
        • update v's key to equal key(u) + weight-function(u, v) // This part is giving me problems as I don't know how implement decreaseKey in priority queue
like image 255
user1641700 Avatar asked Dec 21 '22 10:12

user1641700


2 Answers

I do not think you can implement it in STL container. Remember you can always write your own heap(priority queue) based on vector, but there is a work around:

Keep array of distances you have, lets say d. In you priority queue you put pairs of distances and index of vertex of this distance. When you need to delete some value from queue, do not delete it, just update your value in d array and put new pair into queue.

Every time you take new value from queue, check if distance in pair is actually that good, as in your array d. If not ignore it.

Time is same O(MlogM). Memory is O(MlogM), where M is number of edges.

There is another approach: use RB-Tree, it can insert and delete keys in O(logN) and get minimum as well. You can find implementation in STL of RB-Tree in std::set container.

But, although time complexity is same, RB-Tree works slower and has bigger hidden constant, so it might be slightly slower, appx. 5 times slower. Depends on data, of course .

like image 169
imslavko Avatar answered Dec 24 '22 02:12

imslavko


For the other approach : better than using a std::set. You may use a btree::btree_set (or btree::safe_btree_set). This is an implementation identical to std::set made by google using B-Tree unlike stl which use RB-Tree. This much better than std::set and also O(logN). check the performance comparison : http://code.google.com/p/cpp-btree/wiki/UsageInstructions And it has also a much lower memory footprint.

like image 37
user1811468 Avatar answered Dec 24 '22 00:12

user1811468