00001 
00024 #ifndef PQUEUE_H_
00025 #define PQUEUE_H_
00026 #include "GMetisConfig.h"
00027 #include <algorithm>
00028 #include <vector>
00029 using namespace std;
00030 
00031 template<class T>
00032 struct ListNode{
00033         ListNode(){
00034                 prev=NULL;
00035                 next=NULL;
00036         }
00037         T value;
00038         ListNode* prev;
00039         ListNode* next;
00040 };
00041 
00042 template<class T>
00043 struct KeyValue {
00044         int key;
00045         T value;
00046 };
00047 
00054 template <class T>
00055 class SuperPQueue{
00056 public:
00057         virtual void insert(T value, int priority) = 0;
00058         virtual void remove(T value, int priority) = 0;
00059         virtual void update(T value, int oldPriority, int newPriority) = 0;
00060         virtual T getMax() = 0;
00061         virtual void reset() = 0;
00062         virtual int size() = 0;
00063         virtual ~SuperPQueue(){};
00064 };
00065 
00066 template <class T>
00067 class HeapQueue: public SuperPQueue<T>{
00068 public:
00069         HeapQueue(int maxNumNodes, int maxPriority, int (*mapToInt)(T)){
00070                 numNodes = 0;
00071                 heap.resize(maxNumNodes);
00072                 locator.resize(maxNumNodes); 
00073                 this->mapToInt = mapToInt;
00074                 
00075                 fill(locator.begin(),locator.end(), -1);
00076                 this->maxNumNodes = maxNumNodes;
00077         }
00078         virtual ~HeapQueue(){
00079         }
00080         void insert(T value, int priority) {
00081                 
00082                 int i = numNodes;
00083                 numNodes++;
00084                 while (i > 0) {
00085                         int j = (i - 1) / 2;
00086                         if (heap[j].key < priority) {
00087                                 heap[i].key = heap[j].key;
00088                                 heap[i].value = heap[j].value;
00089                                 locator[(*mapToInt)(heap[i].value)] = i;
00090                                 i = j;
00091                         } else {
00092                                 break;
00093                         }
00094                 }
00095 
00096                 heap[i].key = priority;
00097                 heap[i].value = value;
00098                 locator[(*mapToInt)(value)] = i;
00099         }
00100         void remove(T value, int priority) {
00101                 int id = (*mapToInt)(value);
00102                 int i = locator[id];
00103                 locator[id] = -1;
00104                 if (--numNodes > 0 && (*mapToInt)(heap[numNodes].value) != id) {
00105                         value = heap[numNodes].value;
00106                         int newPriority = heap[numNodes].key;
00107                         int oldPriority = heap[i].key;
00108 
00109                         if (oldPriority < newPriority) {
00110                                 while (i > 0) {
00111                                         int j = (i - 1) >> 1;
00112                                         if (heap[j].key < newPriority) {
00113                                                 heap[i].value = heap[j].value;
00114                                                 heap[i].key = heap[j].key;
00115                                                 locator[(*mapToInt)(heap[i].value)] = i;
00116                                                 i = j;
00117                                         } else
00118                                                 break;
00119                                 }
00120                         } else {
00121                                 int j = 0;
00122                                 while ((j = 2 * i + 1) < numNodes) {
00123                                         if (heap[j].key > newPriority) {
00124                                                 if (j + 1 < numNodes && heap[j + 1].key > heap[j].key)
00125                                                         j = j + 1;
00126                                                 heap[i].value = heap[j].value;
00127                                                 heap[i].key = heap[j].key;
00128                                                 locator[(*mapToInt)(heap[i].value)] = i;
00129                                                 i = j;
00130                                         } else if (j + 1 < numNodes && heap[j + 1].key > newPriority) {
00131                                                 j = j + 1;
00132                                                 heap[i].value = heap[j].value;
00133                                                 heap[i].key = heap[j].key;
00134                                                 locator[(*mapToInt)(heap[i].value)] = i;
00135                                                 i = j;
00136                                         } else
00137                                                 break;
00138                                 }
00139                         }
00140                         heap[i].key = newPriority;
00141                         heap[i].value = value;
00142                         locator[(*mapToInt)(value)] = i;
00143                 }
00144         }
00145         void update(T value, int oldPriority, int newPriority) {
00146                 int i = locator[(*mapToInt)(value)];
00147                 if (oldPriority < newPriority) {
00148                         while (i > 0) {
00149                                 int j = (i - 1) >> 1;
00150                                 if (heap[j].key < newPriority) {
00151                                         heap[i].value = heap[j].value;
00152                                         heap[i].key = heap[j].key;
00153                                         locator[(*mapToInt)(heap[i].value)] = i;
00154                                         i = j;
00155                                 } else
00156                                         break;
00157                         }
00158                 } else {
00159                         int j = 0;
00160                         while ((j = 2 * i + 1) < numNodes) {
00161                                 if (heap[j].key > newPriority) {
00162                                         if (j + 1 < numNodes && heap[j + 1].key > heap[j].key)
00163                                                 j = j + 1;
00164                                         heap[i].value = heap[j].value;
00165                                         heap[i].key = heap[j].key;
00166                                         locator[(*mapToInt)(heap[i].value)] = i;
00167                                         i = j;
00168                                 } else if (j + 1 < numNodes && heap[j + 1].key > newPriority) {
00169                                         j = j + 1;
00170                                         heap[i].value = heap[j].value;
00171                                         heap[i].key = heap[j].key;
00172                                         locator[(*mapToInt)(heap[i].value)] = i;
00173                                         i = j;
00174                                 } else
00175                                         break;
00176                         }
00177                 }
00178                 heap[i].key = newPriority;
00179                 heap[i].value = value;
00180                 locator[(*mapToInt)(value)] = i;
00181         }
00182 
00183         T getMax(){
00184                 if(numNodes == 0){
00185                         assert (false);
00186                         return T();
00187                 }
00188                 numNodes -- ;
00189                 T vtx = heap[0].value;
00190                 locator[(*mapToInt)(vtx)] = -1;
00191                 int i = numNodes;
00192                 if (i > 0) {
00193                         int priority = heap[i].key;
00194                         T node = heap[i].value;
00195                         i = 0;
00196                         int j = 0;
00197                         while ((j = 2 * i + 1) < numNodes) {
00198                                 if (heap[j].key > priority) {
00199                                         if (j + 1 < numNodes && heap[j + 1].key > heap[j].key)
00200                                                 j = j + 1;
00201                                         heap[i].value = heap[j].value;
00202                                         heap[i].key = heap[j].key;
00203                                         locator[(*mapToInt)(heap[i].value)] = i;
00204                                         i = j;
00205                                 } else if (j + 1 < numNodes && heap[j + 1].key > priority) {
00206                                         j = j + 1;
00207                                         heap[i].value = heap[j].value;
00208                                         heap[i].key = heap[j].key;
00209                                         locator[(*mapToInt)(heap[i].value)] = i;
00210                                         i = j;
00211                                 } else
00212                                         break;
00213                         }
00214                         heap[i].key = priority;
00215                         heap[i].value = node;
00216                         locator[(*mapToInt)(node)] = i;
00217                 }
00218                 return vtx;
00219         }
00220         void reset(){
00221                 numNodes = 0;
00222 
00223                 fill(locator.begin(),locator.end(), -1);
00224         }
00225         int size(){
00226                 return numNodes;
00227         }
00228 
00229 private:
00230         typedef KeyValue<T> TKV;
00231         vector<TKV> heap;
00232         vector<int> locator;
00233         int (*mapToInt)(T);
00234         int numNodes;
00235         int maxNumNodes;;
00236 };
00237 
00238 template <class T>
00239 class LimitedPriorityQueue: public SuperPQueue<T>{
00240 public:
00241         LimitedPriorityQueue(int maxNumNodes, int maxPriority, int (*mapToInt)(T)):PLUS_PRIORITYSPAN(500), NEG_PRIORITYSPAN(500){
00242                 pPrioritySpan = min(PLUS_PRIORITYSPAN, maxPriority);
00243                 nPrioritySpan = min(NEG_PRIORITYSPAN, maxPriority);
00244                 nodes = new ListNode<T>[maxNumNodes];
00245                 bucketSize = pPrioritySpan + nPrioritySpan + 1;
00246                 buckets.resize(bucketSize);
00247                 for(int i=0;i<pPrioritySpan + nPrioritySpan + 1;i++){
00248                         buckets[i] = NULL;
00249                 }
00250                 bucketIndex = nPrioritySpan;
00251                 _maxPriority = 0;
00252                 _maxPriority = -nPrioritySpan;
00253                 _mapToInt = mapToInt;
00254                 numNodes = 0;
00255         }
00256         virtual ~LimitedPriorityQueue(){
00257                 delete[] nodes;
00258         }
00259         void insert(T value, int priority) {
00260                 numNodes++;
00261                 int id = (*_mapToInt)(value);
00262 
00263                 nodes[id].value = value;
00264                 ListNode<T>* newNode = &nodes[id];
00265                 newNode->prev = NULL;
00266                 newNode->next = buckets[priority + bucketIndex];
00267                 if (newNode->next != NULL)
00268                         newNode->next->prev = newNode;
00269 
00270                 buckets[priority + bucketIndex] = newNode;
00271                 if (_maxPriority < priority){
00272                         _maxPriority = priority;
00273                 }
00274         }
00275         void remove(T value, int priority) {
00276                 numNodes--;
00277                 ListNode<T>* node = &nodes[(*_mapToInt)(value)];
00278                 if (node->prev != NULL)
00279                         node->prev->next = node->next;
00280                 else
00281                         buckets[priority + bucketIndex] = node->next;
00282                 if (node->next != NULL)
00283                         node->next->prev = node->prev;
00284 
00285                 if (buckets[priority + bucketIndex] == NULL && priority == _maxPriority) {
00286                         if (numNodes == 0)
00287                                 _maxPriority = -nPrioritySpan;
00288                         else
00289                                 for (; buckets[_maxPriority + bucketIndex] == NULL; _maxPriority--);
00290                 }
00291         }
00292         void update(T value, int oldPriority, int newPriority) {
00293                 remove(value, oldPriority);
00294                 insert(value, newPriority);
00295         }
00296         T getMax() {
00297                 if (numNodes == 0){
00298                         cout<<"queue empty..........."<<endl;
00299                         assert (false);
00300                         return T();
00301                 }
00302                 ListNode<T>* tptr = NULL;
00303                 numNodes--;
00304                 tptr = buckets[_maxPriority + bucketIndex];
00305                 buckets[_maxPriority + bucketIndex] = tptr->next;
00306                 if (tptr->next!=NULL) {
00307                         tptr->next->prev = NULL;
00308                 } else {
00309                         if (numNodes == 0) {
00310                                 _maxPriority = -nPrioritySpan;
00311                         } else {
00312                                 for (; buckets[_maxPriority + bucketIndex] == NULL ; _maxPriority--){
00313                                 };
00314                         }
00315                 }
00316                 return tptr->value;
00317         }
00318 
00319         int size(){
00320                 return numNodes;
00321         }
00322         void reset(){
00323                 numNodes = 0;
00324                 _maxPriority = -nPrioritySpan;
00325 
00326                 for (int i = 0; i < bucketSize; i++) {
00327                         buckets[i] = NULL;
00328                 }
00329                 bucketIndex = nPrioritySpan;
00330         }
00331 
00332 private:
00333         int numNodes;
00334         int _maxPriority;
00335         int pPrioritySpan;
00336         int nPrioritySpan;
00337         ListNode<T>* nodes;
00338         vector<ListNode<T>*> buckets;
00339         int bucketSize;
00340         int bucketIndex;
00341         const int PLUS_PRIORITYSPAN;
00342         const int NEG_PRIORITYSPAN;
00343         int (*_mapToInt)(T);
00344 };
00345 
00346 class PQueue{
00347 public:
00348         PQueue(int maxNumNodes, int maxGain) {
00349                 if (maxGain > PLUS_GAINSPAN || maxNumNodes < 500) {
00350 
00351                         internalQueue = new HeapQueue<GNode>(maxNumNodes, maxGain, &gNodeToInt);
00352                 } else {
00353 
00354                         internalQueue = new LimitedPriorityQueue<GNode>(maxNumNodes, maxGain, &gNodeToInt);
00355                 }
00356         }
00357         ~PQueue(){
00358                 delete internalQueue;
00359         }
00360 
00364         void insert(GNode node, int gain) {
00365                 internalQueue->insert(node, gain);
00366         }
00367 
00371         void remove(GNode value, int gain) {
00372                 internalQueue->remove(value, gain);
00373         }
00374 
00378         void update(GNode value, int oldgain, int newgain) {
00379                 internalQueue->update(value, oldgain, newgain);
00380         }
00381 
00385         GNode getMax() {
00386                 return internalQueue->getMax();
00387         }
00388 
00389         int size(){
00390                 return internalQueue->size();
00391         }
00395         void reset() {
00396                 internalQueue->reset();
00397         }
00398 
00399 private:
00400 
00401 
00402         SuperPQueue<GNode>* internalQueue;
00403         static const int PLUS_GAINSPAN = 500;
00404 };
00405 
00406 
00407 
00408 #endif