Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
610 views
in Technique[技术] by (71.8m points)

algorithm - How to implement O(logn) decrease-key operation for min-heap based Priority Queue?

I am working on an application that demonstrates the Djikstra's algorithm, and to use it, I need to restore the heap property when my elements' value is decreased.

The problem regarding the complexity is that when the algorithm changes the value of an element, that element's index in the internal structure (heap in this case) used for the priority queue is unknown. As such, I currently need to do an O(n) search, in order to recover the index, before I can perform an actual decrease-key on it.

Moreover, I am not exactly sure about the actual code needed for the operation. I am using the D-Heap here for my Priority Queue. Pseudocode would help, but I would prefer an example in Java on how this should be done.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can do following: store a hashmap inside your heap that maps your heap values to heap indexes. Then you should extend your usual heap-logic just a bit:

on Swap(i, j): 
    map[value[i]] = j; 
    map[value[j]] = i;

on Insert(key, value): 
    map.Add(value, heapSize) in the beginning;

on ExtractMin: 
    map.Remove(extractedValue) in the end;

on UpdateKey(value, newKey): 
    index = map[value]; 
    keys[index] = newKey; 

BubbleUp(index) in case of DecreaseKey, and BubbleDown/Heapify(index) in case of IncreaseKey, to restore min-heap-property.

Here's my C# implementation: http://pastebin.com/kkZn123m

Insert and ExtractMin call Swap log(N) times, when restoring heap property. And you're adding O(1) overhead to Swap, so both operations remain O(log(n)). UpdateKey is also log(N): first you lookup index in a hashmap for O(1), then you're restoring heap property for O(log(N)) as you do in Insert/ExtractMin.

Important note: using values for index lookup will require that they are UNIQUE. If you're not ok with this condition, you will have to add some uniqueue id to your key-value pairs and maintain mapping between this uniqueue id and heap index instead of value-index mapping. But for Dijkstra it's not needed, as your values will be graph nodes and you don't want duplicate nodes in your priority queue.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...