00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include <iostream>
00030 using namespace std;
00031
00032 #include "../sbpl/headers.h"
00033
00034
00035 void heaperror(const char* ErrorString)
00036 {
00037
00038 SBPL_PRINTF("%s\n", ErrorString);
00039 throw new SBPL_Exception();
00040 }
00041
00042
00043
00044 CKey InfiniteKey()
00045 {
00046 CKey key;
00047 key.SetKeytoInfinity();
00048 return key;
00049
00050 }
00051
00052
00053
00054 CHeap::CHeap()
00055 {
00056 percolates = 0;
00057 currentsize = 0;
00058 allocated = HEAPSIZE_INIT;
00059
00060 heap = new heapelement[allocated];
00061
00062 }
00063
00064 CHeap::~CHeap()
00065 {
00066 int i;
00067 for (i=1; i<=currentsize; ++i)
00068 heap[i].heapstate->heapindex = 0;
00069
00070 delete [] heap;
00071 }
00072
00073
00074 void CHeap::percolatedown(int hole, heapelement tmp)
00075 {
00076 int child;
00077
00078 if (currentsize != 0)
00079 {
00080
00081 for (; 2*hole <= currentsize; hole = child)
00082 {
00083 child = 2*hole;
00084
00085 if (child != currentsize && heap[child+1].key < heap[child].key)
00086 ++child;
00087 if (heap[child].key < tmp.key)
00088 {
00089 percolates += 1;
00090 heap[hole] = heap[child];
00091 heap[hole].heapstate->heapindex = hole;
00092 }
00093 else
00094 break;
00095 }
00096 heap[hole] = tmp;
00097 heap[hole].heapstate->heapindex = hole;
00098 }
00099 }
00100
00101 void CHeap::percolateup(int hole, heapelement tmp)
00102 {
00103 if (currentsize != 0)
00104 {
00105 for (; hole > 1 && tmp.key < heap[hole/2].key; hole /= 2)
00106 {
00107 percolates += 1;
00108 heap[hole] = heap[hole/2];
00109 heap[hole].heapstate->heapindex = hole;
00110 }
00111 heap[hole] = tmp;
00112 heap[hole].heapstate->heapindex = hole;
00113 }
00114 }
00115
00116 void CHeap::percolateupordown(int hole, heapelement tmp)
00117 {
00118 if (currentsize != 0)
00119 {
00120 if (hole > 1 && heap[hole/2].key > tmp.key)
00121 percolateup(hole, tmp);
00122 else
00123 percolatedown(hole, tmp);
00124 }
00125 }
00126
00127 bool CHeap::emptyheap()
00128 {
00129 return currentsize == 0;
00130 }
00131
00132
00133 bool CHeap::fullheap()
00134 {
00135 return currentsize == HEAPSIZE-1;
00136 }
00137
00138 bool CHeap::inheap(AbstractSearchState *AbstractSearchState)
00139 {
00140 return (AbstractSearchState->heapindex != 0);
00141 }
00142
00143
00144 CKey CHeap::getkeyheap(AbstractSearchState *AbstractSearchState)
00145 {
00146 if (AbstractSearchState->heapindex == 0)
00147 heaperror("GetKey: AbstractSearchState is not in heap");
00148
00149 return heap[AbstractSearchState->heapindex].key;
00150 }
00151
00152 void CHeap::makeemptyheap()
00153 {
00154 int i;
00155
00156 for (i=1; i<=currentsize; ++i)
00157 heap[i].heapstate->heapindex = 0;
00158 currentsize = 0;
00159 }
00160
00161 void CHeap::makeheap()
00162 {
00163 int i;
00164
00165 for (i = currentsize / 2; i > 0; i--)
00166 {
00167 percolatedown(i, heap[i]);
00168 }
00169 }
00170
00171 void CHeap::growheap()
00172 {
00173 heapelement* newheap;
00174 int i;
00175
00176 SBPL_PRINTF("growing heap size from %d ", allocated);
00177
00178 allocated = 2*allocated;
00179 if(allocated > HEAPSIZE)
00180 allocated = HEAPSIZE;
00181
00182 SBPL_PRINTF("to %d\n", allocated);
00183
00184 newheap = new heapelement[allocated];
00185
00186 for (i=0; i<=currentsize; ++i)
00187 newheap[i] = heap[i];
00188
00189 delete [] heap;
00190
00191 heap = newheap;
00192 }
00193
00194
00195 void CHeap::sizecheck()
00196 {
00197
00198 if (fullheap())
00199 heaperror("insertheap: heap is full");
00200 else if(currentsize == allocated-1)
00201 {
00202 growheap();
00203 }
00204 }
00205
00206
00207
00208 void CHeap::insertheap(AbstractSearchState *AbstractSearchState, CKey key)
00209 {
00210 heapelement tmp;
00211 char strTemp[100];
00212
00213
00214 sizecheck();
00215
00216 if (AbstractSearchState->heapindex != 0)
00217 {
00218 sprintf(strTemp, "insertheap: AbstractSearchState is already in heap");
00219 heaperror(strTemp);
00220 }
00221 tmp.heapstate = AbstractSearchState;
00222 tmp.key = key;
00223 percolateup(++currentsize, tmp);
00224 }
00225
00226 void CHeap::deleteheap(AbstractSearchState *AbstractSearchState)
00227 {
00228 if (AbstractSearchState->heapindex == 0)
00229 heaperror("deleteheap: AbstractSearchState is not in heap");
00230 percolateupordown(AbstractSearchState->heapindex, heap[currentsize--]);
00231 AbstractSearchState->heapindex = 0;
00232 }
00233
00234 void CHeap::updateheap(AbstractSearchState *AbstractSearchState, CKey NewKey)
00235 {
00236 if (AbstractSearchState->heapindex == 0)
00237 heaperror("Updateheap: AbstractSearchState is not in heap");
00238 if (heap[AbstractSearchState->heapindex].key != NewKey)
00239 {
00240 heap[AbstractSearchState->heapindex].key = NewKey;
00241 percolateupordown(AbstractSearchState->heapindex, heap[AbstractSearchState->heapindex]);
00242 }
00243 }
00244
00245 void CHeap::insert_unsafe(AbstractSearchState *AbstractSearchState, CKey key) {
00246 heapelement tmp;
00247 char strTemp[100];
00248
00249
00250 sizecheck();
00251
00252 if (AbstractSearchState->heapindex != 0)
00253 {
00254 sprintf(strTemp, "insertheap: AbstractSearchState is already in heap");
00255 heaperror(strTemp);
00256 }
00257 tmp.heapstate = AbstractSearchState;
00258 tmp.key = key;
00259
00260
00261 ++ currentsize;
00262 heap[currentsize] = tmp;
00263 heap[currentsize].heapstate->heapindex = currentsize;
00264
00265
00266 }
00267
00268
00269 void CHeap::deleteheap_unsafe(AbstractSearchState *AbstractSearchState) {
00270 if (AbstractSearchState->heapindex == 0)
00271 heaperror("deleteheap: AbstractSearchState is not in heap");
00272
00273 heap[AbstractSearchState->heapindex] = heap[currentsize];
00274 --currentsize;
00275
00276 heap[AbstractSearchState->heapindex].heapstate->heapindex = AbstractSearchState->heapindex;
00277 AbstractSearchState->heapindex = 0;
00278
00279 }
00280
00281 void CHeap::updateheap_unsafe(AbstractSearchState *AbstractSearchState, CKey NewKey){
00282
00283 if (AbstractSearchState->heapindex == 0)
00284 heaperror("Updateheap: AbstractSearchState is not in heap");
00285 if (heap[AbstractSearchState->heapindex].key != NewKey) {
00286 heap[AbstractSearchState->heapindex].key = NewKey;
00287 }
00288 }
00289
00290
00291 AbstractSearchState* CHeap::getminheap()
00292 {
00293 if (currentsize == 0)
00294 heaperror("GetMinheap: heap is empty");
00295 return heap[1].heapstate;
00296 }
00297
00298 AbstractSearchState* CHeap::getminheap(CKey& ReturnKey)
00299 {
00300 if (currentsize == 0)
00301 {
00302 heaperror("GetMinheap: heap is empty");
00303 ReturnKey = InfiniteKey();
00304 }
00305 ReturnKey = heap[1].key;
00306 return heap[1].heapstate;
00307 }
00308
00309 CKey CHeap::getminkeyheap()
00310 {
00311 CKey ReturnKey;
00312 if (currentsize == 0)
00313 return InfiniteKey();
00314 ReturnKey = heap[1].key;
00315 return ReturnKey;
00316 }
00317
00318 AbstractSearchState* CHeap::deleteminheap()
00319 {
00320 AbstractSearchState *AbstractSearchState;
00321
00322 if (currentsize == 0)
00323 heaperror("DeleteMin: heap is empty");
00324
00325 AbstractSearchState = heap[1].heapstate;
00326 AbstractSearchState->heapindex = 0;
00327 percolatedown(1, heap[currentsize--]);
00328 return AbstractSearchState;
00329 }
00330
00331
00332
00333
00334
00335 CIntHeap::CIntHeap()
00336 {
00337 percolates = 0;
00338 currentsize = 0;
00339 allocated = HEAPSIZE_INIT;
00340
00341 heap = new heapintelement[allocated];
00342
00343 }
00344
00345 CIntHeap::CIntHeap(int initial_size)
00346 {
00347 percolates = 0;
00348 currentsize = 0;
00349 allocated = initial_size;
00350
00351 heap = new heapintelement[allocated];
00352
00353 }
00354
00355
00356
00357 CIntHeap::~CIntHeap()
00358 {
00359 int i;
00360 for (i=1; i<=currentsize; ++i)
00361 heap[i].heapstate->heapindex = 0;
00362
00363 delete [] heap;
00364 }
00365
00366
00367 void CIntHeap::percolatedown(int hole, heapintelement tmp)
00368 {
00369 int child;
00370
00371 if (currentsize != 0)
00372 {
00373
00374 for (; 2*hole <= currentsize; hole = child)
00375 {
00376 child = 2*hole;
00377
00378 if (child != currentsize && heap[child+1].key < heap[child].key)
00379 ++child;
00380 if (heap[child].key < tmp.key)
00381 {
00382 percolates += 1;
00383 heap[hole] = heap[child];
00384 heap[hole].heapstate->heapindex = hole;
00385 }
00386 else
00387 break;
00388 }
00389 heap[hole] = tmp;
00390 heap[hole].heapstate->heapindex = hole;
00391 }
00392 }
00393
00394 void CIntHeap::percolateup(int hole, heapintelement tmp)
00395 {
00396 if (currentsize != 0)
00397 {
00398 for (; hole > 1 && tmp.key < heap[hole/2].key; hole /= 2)
00399 {
00400 percolates += 1;
00401 heap[hole] = heap[hole/2];
00402 heap[hole].heapstate->heapindex = hole;
00403 }
00404 heap[hole] = tmp;
00405 heap[hole].heapstate->heapindex = hole;
00406 }
00407 }
00408
00409 void CIntHeap::percolateupordown(int hole, heapintelement tmp)
00410 {
00411 if (currentsize != 0)
00412 {
00413 if (hole > 1 && heap[hole/2].key > tmp.key)
00414 percolateup(hole, tmp);
00415 else
00416 percolatedown(hole, tmp);
00417 }
00418 }
00419
00420 bool CIntHeap::emptyheap()
00421 {
00422 return currentsize == 0;
00423 }
00424
00425
00426 bool CIntHeap::fullheap()
00427 {
00428 return currentsize == HEAPSIZE-1;
00429 }
00430
00431 bool CIntHeap::inheap(AbstractSearchState *AbstractSearchState)
00432 {
00433 return (AbstractSearchState->heapindex != 0);
00434 }
00435
00436
00437 int CIntHeap::getkeyheap(AbstractSearchState *AbstractSearchState)
00438 {
00439 if (AbstractSearchState->heapindex == 0)
00440 heaperror("GetKey: AbstractSearchState is not in heap");
00441
00442 return heap[AbstractSearchState->heapindex].key;
00443 }
00444
00445 void CIntHeap::makeemptyheap()
00446 {
00447 int i;
00448
00449 for (i=1; i<=currentsize; ++i)
00450 heap[i].heapstate->heapindex = 0;
00451 currentsize = 0;
00452 }
00453
00454 void CIntHeap::makeheap()
00455 {
00456 int i;
00457
00458 for (i = currentsize / 2; i > 0; i--)
00459 {
00460 percolatedown(i, heap[i]);
00461 }
00462 }
00463
00464 void CIntHeap::growheap()
00465 {
00466 heapintelement* newheap;
00467 int i;
00468
00469 SBPL_PRINTF("growing heap size from %d ", allocated);
00470
00471 allocated = 2*allocated;
00472 if(allocated > HEAPSIZE)
00473 allocated = HEAPSIZE;
00474
00475 SBPL_PRINTF("to %d\n", allocated);
00476
00477 newheap = new heapintelement[allocated];
00478
00479 for (i=0; i<=currentsize; ++i)
00480 newheap[i] = heap[i];
00481
00482 delete [] heap;
00483
00484 heap = newheap;
00485 }
00486
00487
00488 void CIntHeap::sizecheck()
00489 {
00490
00491 if (fullheap())
00492 heaperror("insertheap: heap is full");
00493 else if(currentsize == allocated-1)
00494 {
00495 growheap();
00496 }
00497 }
00498
00499
00500
00501 void CIntHeap::insertheap(AbstractSearchState *AbstractSearchState, int key)
00502 {
00503 heapintelement tmp;
00504 char strTemp[100];
00505
00506 sizecheck();
00507
00508 if (AbstractSearchState->heapindex != 0)
00509 {
00510 sprintf(strTemp, "insertheap: AbstractSearchState is already in heap");
00511 heaperror(strTemp);
00512 }
00513 tmp.heapstate = AbstractSearchState;
00514 tmp.key = key;
00515 percolateup(++currentsize, tmp);
00516 }
00517
00518 void CIntHeap::deleteheap(AbstractSearchState *AbstractSearchState)
00519 {
00520 if (AbstractSearchState->heapindex == 0)
00521 heaperror("deleteheap: AbstractSearchState is not in heap");
00522 percolateupordown(AbstractSearchState->heapindex, heap[currentsize--]);
00523 AbstractSearchState->heapindex = 0;
00524 }
00525
00526 void CIntHeap::updateheap(AbstractSearchState *AbstractSearchState, int NewKey)
00527 {
00528 if (AbstractSearchState->heapindex == 0)
00529 heaperror("Updateheap: AbstractSearchState is not in heap");
00530 if (heap[AbstractSearchState->heapindex].key != NewKey)
00531 {
00532 heap[AbstractSearchState->heapindex].key = NewKey;
00533 percolateupordown(AbstractSearchState->heapindex, heap[AbstractSearchState->heapindex]);
00534 }
00535 }
00536
00537 AbstractSearchState* CIntHeap::getminheap()
00538 {
00539 if (currentsize == 0)
00540 heaperror("GetMinheap: heap is empty");
00541 return heap[1].heapstate;
00542 }
00543
00544 AbstractSearchState* CIntHeap::getminheap(int& ReturnKey)
00545 {
00546 if (currentsize == 0)
00547 {
00548 heaperror("GetMinheap: heap is empty");
00549 }
00550 ReturnKey = heap[1].key;
00551 return heap[1].heapstate;
00552 }
00553
00554 int CIntHeap::getminkeyheap()
00555 {
00556 int ReturnKey;
00557 if (currentsize == 0)
00558 return INFINITECOST;
00559 ReturnKey = heap[1].key;
00560 return ReturnKey;
00561 }
00562
00563 AbstractSearchState* CIntHeap::deleteminheap()
00564 {
00565 AbstractSearchState *AbstractSearchState;
00566
00567 if (currentsize == 0)
00568 heaperror("DeleteMin: heap is empty");
00569
00570 AbstractSearchState = heap[1].heapstate;
00571 AbstractSearchState->heapindex = 0;
00572 percolatedown(1, heap[currentsize--]);
00573 return AbstractSearchState;
00574 }
00575
00576
00577