hp2FEM  0.1
src/metis-5.0/GKlib/gk_mkpqueue.h
Go to the documentation of this file.
00001 
00011 #ifndef _GK_MKPQUEUE_H
00012 #define _GK_MKPQUEUE_H
00013 
00014 
00015 #define GK_MKPQUEUE(FPRFX, PQT, KVT, KT, VT, KVMALLOC, KMAX, KEY_LT)\
00016 /*************************************************************************/\
00017 \
00018 /**************************************************************************/\
00019 PQT *FPRFX ## Create(size_t maxnodes)\
00020 {\
00021   PQT *queue; \
00022 \
00023   queue = (PQT *)gk_malloc(sizeof(PQT), "gk_pqCreate: queue");\
00024   FPRFX ## Init(queue, maxnodes);\
00025 \
00026   return queue;\
00027 }\
00028 \
00029 \
00030 /*************************************************************************/\
00031 \
00032 /**************************************************************************/\
00033 void FPRFX ## Init(PQT *queue, size_t maxnodes)\
00034 {\
00035   queue->nnodes = 0;\
00036   queue->maxnodes = maxnodes;\
00037 \
00038   queue->heap    = KVMALLOC(maxnodes, "gk_PQInit: heap");\
00039   queue->locator = gk_idxsmalloc(maxnodes, -1, "gk_PQInit: locator");\
00040 }\
00041 \
00042 \
00043 /*************************************************************************/\
00044 \
00045 /**************************************************************************/\
00046 void FPRFX ## Reset(PQT *queue)\
00047 {\
00048   gk_idx_t i;\
00049   gk_idx_t *locator=queue->locator;\
00050   KVT *heap=queue->heap;\
00051 \
00052   for (i=queue->nnodes-1; i>=0; i--)\
00053     locator[heap[i].val] = -1;\
00054   queue->nnodes = 0;\
00055 }\
00056 \
00057 \
00058 /*************************************************************************/\
00059 \
00060 /**************************************************************************/\
00061 void FPRFX ## Free(PQT *queue)\
00062 {\
00063   gk_free((void **)&queue->heap, &queue->locator, LTERM);\
00064   queue->maxnodes = 0;\
00065 }\
00066 \
00067 \
00068 /*************************************************************************/\
00069 \
00071 /**************************************************************************/\
00072 void FPRFX ## Destroy(PQT *queue)\
00073 {\
00074   FPRFX ## Free(queue);\
00075   gk_free((void **)&queue, LTERM);\
00076 }\
00077 \
00078 \
00079 /*************************************************************************/\
00080 \
00081 /**************************************************************************/\
00082 size_t FPRFX ## Length(PQT *queue)\
00083 {\
00084   return queue->nnodes;\
00085 }\
00086 \
00087 \
00088 /*************************************************************************/\
00089 \
00090 /**************************************************************************/\
00091 int FPRFX ## Insert(PQT *queue, VT node, KT key)\
00092 {\
00093   gk_idx_t i, j;\
00094   gk_idx_t *locator=queue->locator;\
00095   KVT *heap=queue->heap;\
00096 \
00097   ASSERT2(FPRFX ## CheckHeap(queue));\
00098 \
00099   ASSERT(locator[node] == -1);\
00100 \
00101   i = queue->nnodes++;\
00102   while (i > 0) {\
00103     j = (i-1)>>1;\
00104     if (KEY_LT(key, heap[j].key)) {\
00105       heap[i] = heap[j];\
00106       locator[heap[i].val] = i;\
00107       i = j;\
00108     }\
00109     else\
00110       break;\
00111   }\
00112   ASSERT(i >= 0);\
00113   heap[i].key   = key;\
00114   heap[i].val   = node;\
00115   locator[node] = i;\
00116 \
00117   ASSERT2(FPRFX ## CheckHeap(queue));\
00118 \
00119   return 0;\
00120 }\
00121 \
00122 \
00123 /*************************************************************************/\
00124 \
00125 /**************************************************************************/\
00126 int FPRFX ## Delete(PQT *queue, VT node)\
00127 {\
00128   gk_idx_t i, j, nnodes;\
00129   KT newkey, oldkey;\
00130   gk_idx_t *locator=queue->locator;\
00131   KVT *heap=queue->heap;\
00132 \
00133   ASSERT(locator[node] != -1);\
00134   ASSERT(heap[locator[node]].val == node);\
00135 \
00136   ASSERT2(FPRFX ## CheckHeap(queue));\
00137 \
00138   i = locator[node];\
00139   locator[node] = -1;\
00140 \
00141   if (--queue->nnodes > 0 && heap[queue->nnodes].val != node) {\
00142     node   = heap[queue->nnodes].val;\
00143     newkey = heap[queue->nnodes].key;\
00144     oldkey = heap[i].key;\
00145 \
00146     if (KEY_LT(newkey, oldkey)) { /* Filter-up */\
00147       while (i > 0) {\
00148         j = (i-1)>>1;\
00149         if (KEY_LT(newkey, heap[j].key)) {\
00150           heap[i] = heap[j];\
00151           locator[heap[i].val] = i;\
00152           i = j;\
00153         }\
00154         else\
00155           break;\
00156       }\
00157     }\
00158     else { /* Filter down */\
00159       nnodes = queue->nnodes;\
00160       while ((j=(i<<1)+1) < nnodes) {\
00161         if (KEY_LT(heap[j].key, newkey)) {\
00162           if (j+1 < nnodes && KEY_LT(heap[j+1].key, heap[j].key))\
00163             j++;\
00164           heap[i] = heap[j];\
00165           locator[heap[i].val] = i;\
00166           i = j;\
00167         }\
00168         else if (j+1 < nnodes && KEY_LT(heap[j+1].key, newkey)) {\
00169           j++;\
00170           heap[i] = heap[j];\
00171           locator[heap[i].val] = i;\
00172           i = j;\
00173         }\
00174         else\
00175           break;\
00176       }\
00177     }\
00178 \
00179     heap[i].key   = newkey;\
00180     heap[i].val   = node;\
00181     locator[node] = i;\
00182   }\
00183 \
00184   ASSERT2(FPRFX ## CheckHeap(queue));\
00185 \
00186   return 0;\
00187 }\
00188 \
00189 \
00190 /*************************************************************************/\
00191  \
00192 /**************************************************************************/\
00193 int FPRFX ## Update(PQT *queue, VT node, KT newkey)\
00194 {\
00195   gk_idx_t i, j, nnodes;\
00196   KT oldkey;\
00197   gk_idx_t *locator=queue->locator;\
00198   KVT *heap=queue->heap;\
00199 \
00200   oldkey = heap[locator[node]].key;\
00201 \
00202   ASSERT(locator[node] != -1);\
00203   ASSERT(heap[locator[node]].val == node);\
00204   ASSERT2(FPRFX ## CheckHeap(queue));\
00205 \
00206   i = locator[node];\
00207 \
00208   if (KEY_LT(newkey, oldkey)) { /* Filter-up */\
00209     while (i > 0) {\
00210       j = (i-1)>>1;\
00211       if (KEY_LT(newkey, heap[j].key)) {\
00212         heap[i] = heap[j];\
00213         locator[heap[i].val] = i;\
00214         i = j;\
00215       }\
00216       else\
00217         break;\
00218     }\
00219   }\
00220   else { /* Filter down */\
00221     nnodes = queue->nnodes;\
00222     while ((j=(i<<1)+1) < nnodes) {\
00223       if (KEY_LT(heap[j].key, newkey)) {\
00224         if (j+1 < nnodes && KEY_LT(heap[j+1].key, heap[j].key))\
00225           j++;\
00226         heap[i] = heap[j];\
00227         locator[heap[i].val] = i;\
00228         i = j;\
00229       }\
00230       else if (j+1 < nnodes && KEY_LT(heap[j+1].key, newkey)) {\
00231         j++;\
00232         heap[i] = heap[j];\
00233         locator[heap[i].val] = i;\
00234         i = j;\
00235       }\
00236       else\
00237         break;\
00238     }\
00239   }\
00240 \
00241   heap[i].key   = newkey;\
00242   heap[i].val   = node;\
00243   locator[node] = i;\
00244 \
00245   ASSERT2(FPRFX ## CheckHeap(queue));\
00246 \
00247   return 0;\
00248 }\
00249 \
00250 \
00251 /*************************************************************************/\
00252 \
00254 /**************************************************************************/\
00255 VT FPRFX ## GetTop(PQT *queue)\
00256 {\
00257   gk_idx_t i, j;\
00258   gk_idx_t *locator;\
00259   KVT *heap;\
00260   VT vtx, node;\
00261   KT key;\
00262 \
00263   ASSERT2(FPRFX ## CheckHeap(queue));\
00264 \
00265   if (queue->nnodes == 0)\
00266     return -1;\
00267 \
00268   queue->nnodes--;\
00269 \
00270   heap    = queue->heap;\
00271   locator = queue->locator;\
00272 \
00273   vtx = heap[0].val;\
00274   locator[vtx] = -1;\
00275 \
00276   if ((i = queue->nnodes) > 0) {\
00277     key  = heap[i].key;\
00278     node = heap[i].val;\
00279     i = 0;\
00280     while ((j=2*i+1) < queue->nnodes) {\
00281       if (KEY_LT(heap[j].key, key)) {\
00282         if (j+1 < queue->nnodes && KEY_LT(heap[j+1].key, heap[j].key))\
00283           j = j+1;\
00284         heap[i] = heap[j];\
00285         locator[heap[i].val] = i;\
00286         i = j;\
00287       }\
00288       else if (j+1 < queue->nnodes && KEY_LT(heap[j+1].key, key)) {\
00289         j = j+1;\
00290         heap[i] = heap[j];\
00291         locator[heap[i].val] = i;\
00292         i = j;\
00293       }\
00294       else\
00295         break;\
00296     }\
00297 \
00298     heap[i].key   = key;\
00299     heap[i].val   = node;\
00300     locator[node] = i;\
00301   }\
00302 \
00303   ASSERT2(FPRFX ## CheckHeap(queue));\
00304   return vtx;\
00305 }\
00306 \
00307 \
00308 /*************************************************************************/\
00309 \
00311 /**************************************************************************/\
00312 VT FPRFX ## SeeTopVal(PQT *queue)\
00313 {\
00314   return (queue->nnodes == 0 ? -1 : queue->heap[0].val);\
00315 }\
00316 \
00317 \
00318 /*************************************************************************/\
00319 \
00321 /**************************************************************************/\
00322 KT FPRFX ## SeeTopKey(PQT *queue)\
00323 {\
00324   return (queue->nnodes == 0 ? KMAX : queue->heap[0].key);\
00325 }\
00326 \
00327 \
00328 /*************************************************************************/\
00329 \
00330 /**************************************************************************/\
00331 KT FPRFX ## SeeKey(PQT *queue, VT node)\
00332 {\
00333   gk_idx_t *locator;\
00334   KVT *heap;\
00335 \
00336   heap    = queue->heap;\
00337   locator = queue->locator;\
00338 \
00339   return heap[locator[node]].key;\
00340 }\
00341 \
00342 \
00343 /*************************************************************************/\
00344 \
00347 /**************************************************************************/\
00348 /*\
00349 VT FPRFX ## SeeConstraintTop(PQT *queue, KT maxwgt, KT *wgts)\
00350 {\
00351   gk_idx_t i;\
00352 \
00353   if (queue->nnodes == 0)\
00354     return -1;\
00355 \
00356   if (maxwgt <= 1000)\
00357     return FPRFX ## SeeTopVal(queue);\
00358 \
00359   for (i=0; i<queue->nnodes; i++) {\
00360     if (queue->heap[i].key > 0) {\
00361       if (wgts[queue->heap[i].val] <= maxwgt)\
00362         return queue->heap[i].val;\
00363     }\
00364     else {\
00365       if (queue->heap[i/2].key <= 0)\
00366         break;\
00367     }\
00368   }\
00369 \
00370   return queue->heap[0].val;\
00371 \
00372 }\
00373 */\
00374 \
00375 \
00376 /*************************************************************************/\
00377 \
00378 /**************************************************************************/\
00379 int FPRFX ## CheckHeap(PQT *queue)\
00380 {\
00381   gk_idx_t i, j;\
00382   size_t nnodes;\
00383   gk_idx_t *locator;\
00384   KVT *heap;\
00385 \
00386   heap    = queue->heap;\
00387   locator = queue->locator;\
00388   nnodes  = queue->nnodes;\
00389 \
00390   if (nnodes == 0)\
00391     return 1;\
00392 \
00393   ASSERT(locator[heap[0].val] == 0);\
00394   for (i=1; i<nnodes; i++) {\
00395     ASSERT(locator[heap[i].val] == i);\
00396     ASSERT(!KEY_LT(heap[i].key, heap[(i-1)/2].key));\
00397   }\
00398   for (i=1; i<nnodes; i++)\
00399     ASSERT(!KEY_LT(heap[i].key, heap[0].key));\
00400 \
00401   for (j=i=0; i<queue->maxnodes; i++) {\
00402     if (locator[i] != -1)\
00403       j++;\
00404   }\
00405   ASSERTP(j == nnodes, ("%jd %jd\n", (intmax_t)j, (intmax_t)nnodes));\
00406 \
00407   return 1;\
00408 }\
00409 
00410 
00411 #define GK_MKPQUEUE_PROTO(FPRFX, PQT, KT, VT)\
00412   PQT *  FPRFX ## Create(size_t maxnodes);\
00413   void   FPRFX ## Init(PQT *queue, size_t maxnodes);\
00414   void   FPRFX ## Reset(PQT *queue);\
00415   void   FPRFX ## Free(PQT *queue);\
00416   void   FPRFX ## Destroy(PQT *queue);\
00417   size_t FPRFX ## Length(PQT *queue);\
00418   int    FPRFX ## Insert(PQT *queue, VT node, KT key);\
00419   int    FPRFX ## Delete(PQT *queue, VT node);\
00420   int    FPRFX ## Update(PQT *queue, VT node, KT newkey);\
00421   VT     FPRFX ## GetTop(PQT *queue);\
00422   VT     FPRFX ## SeeTopVal(PQT *queue);\
00423   KT     FPRFX ## SeeTopKey(PQT *queue);\
00424   KT     FPRFX ## SeeKey(PQT *queue, VT node);\
00425   VT     FPRFX ## SeeConstraintTop(PQT *queue, KT maxwgt, KT *wgts);\
00426   int    FPRFX ## CheckHeap(PQT *queue);\
00427 
00428 
00429 /* This is how these macros are used
00430 GK_MKPQUEUE(gk_dkvPQ, gk_dkvPQ_t, double, gk_idx_t, gk_dkvmalloc, DBL_MAX)
00431 GK_MKPQUEUE_PROTO(gk_dkvPQ, gk_dkvPQ_t, double, gk_idx_t)
00432 */
00433 
00434 
00435 #endif
 All Classes Files Functions Variables Typedefs Friends Defines