Go to the documentation of this file.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