hp2FEM
0.1
|
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