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
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
#include <stdio.h>
00048
#include <string.h>
00049
#include <blah.h>
00050
00051
00052
#define TA_DEBUG 0
00053
00054
00055
00056
00057
00058
00059 struct TANodeStruct {
00060 int parent;
00061 int better;
00062 int worse;
00063 double score;
00064 Pointer
state;
00065 };
00066
00067
00068
00069
00070 struct TreeAgendaStruct {
00071 int size;
00072 int maxsize;
00073 int maxSizeSoFar;
00074 Boolean
verbose;
00075 Boolean
truncationWarning;
00076 int free;
00077 int root;
00078 int best;
00079 int worst;
00080 VoidFunction *
freeState;
00081 TANodeStruct *
nodes;
00082 };
00083
00084
00085
00086
00087
00088 struct TreeAgendaIteratorStruct {
00089 TreeAgenda
treeagenda;
00090 int nextNode;
00091 };
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104 void taPrintNode(TreeAgenda a,
int index)
00105 {
00106 printf(
"[ %d ", index);
00107
00108
if (index >= 0) {
00109 printf(
"p %d ", a->nodes[index].parent);
00110
if (a->nodes[index].parent >= 0) {
00111 printf(
" p's b %d p's w %d p's p %d ",
00112 a->nodes[a->nodes[index].parent].better,
00113 a->nodes[a->nodes[index].parent].worse,
00114 a->nodes[a->nodes[index].parent].parent);
00115 }
00116 printf(
"b %d ", a->nodes[index].better);
00117
if (a->nodes[index].better >= 0) {
00118 printf(
" b's b %d b's w %d b's p %d ",
00119 a->nodes[a->nodes[index].better].better,
00120 a->nodes[a->nodes[index].better].worse,
00121 a->nodes[a->nodes[index].better].parent);
00122 }
00123 printf(
"w %d ", a->nodes[index].worse);
00124
if (a->nodes[index].worse >= 0) {
00125 printf(
" w's b %d w's w %d w's p %d ",
00126 a->nodes[a->nodes[index].worse].better,
00127 a->nodes[a->nodes[index].worse].worse,
00128 a->nodes[a->nodes[index].worse].parent);
00129 }
00130 }
00131 printf(
"]");
00132 }
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145 int taCheckNode(TreeAgenda a,
int index, Boolean recursive, Boolean better)
00146 {
00147
int count;
00148
00149
if (index < 0) {
00150
return (0);
00151 }
00152
00153
if (a->best >= 0 && a->nodes[a->best].better >= 0) {
00154 printf(
"DEBUG: best inconsistency\n index ");
00155
taPrintNode(a, index);
00156 printf(
"\n best ");
00157
taPrintNode(a, a->best);
00158 printf(
"\n");
00159 abort();
00160 }
00161
00162
if (a->worst >= 0 && a->nodes[a->worst].worse >= 0) {
00163 printf(
"DEBUG: worst inconsistency\n index ");
00164
taPrintNode(a, index);
00165 printf(
"\n worst ");
00166
taPrintNode(a, a->worst);
00167 printf(
"\n");
00168 abort();
00169 }
00170
00171
if ((a->root != index && a->nodes[index].parent < 0)
00172 || (a->nodes[index].parent >= 0 &&
00173 ((better && a->nodes[a->nodes[index].parent].better != index)
00174 || (!better && a->nodes[a->nodes[index].parent].worse != index)))) {
00175 printf(
"ERROR: %s inconsistency in node ", better &&
00176 a->nodes[a->nodes[index].parent].better !=
00177 index ?
"left" :
"right");
00178
taPrintNode(a, index);
00179 printf(
"\n");
00180 abort();
00181 }
00182
00183 count = 1;
00184
if (recursive) {
00185 count +=
taCheckNode(a, a->nodes[index].better, recursive, TRUE);
00186 count +=
taCheckNode(a, a->nodes[index].worse, recursive, FALSE);
00187 }
00188
00189
return (count);
00190 }
00191
00192
00193
00194
00195
00196
00197
00198
00199 int taDeleteNode(TreeAgenda a,
int index, Boolean
delete)
00200 {
00201 TANode node;
00202
int count;
00203
00204
if (index < 0) {
00205
return (0);
00206 }
00207
00208 node = &a->nodes[index];
00209
00210 count = 1;
00211 count +=
taDeleteNode(a, node->better,
delete);
00212 count +=
taDeleteNode(a, node->worse,
delete);
00213
00214
if (
delete) {
00215 (*a->freeState) (node->state);
00216
00217 node->parent = a->free;
00218 a->free = index;
00219 a->size--;
00220
if (index == a->root) {
00221 a->root = -1;
00222 printf(
"DEBUG: taDeleteNode, %d was root, resetting\n", index);
00223 }
00224 }
00225
00226
return (count);
00227 }
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239 TreeAgenda
taNew(
int maxsize, VoidFunction *f)
00240 {
00241
int i;
00242 TreeAgenda a;
00243
00244
if (maxsize < 1) {
00245 printf(
"WARNING: minimum size of agenda is 2, %d is too small\n", maxsize);
00246
00247
00248
00249
00250 maxsize = 2;
00251 }
00252
00253 a = (TreeAgenda) memMalloc(
sizeof (
TreeAgendaStruct));
00254 a->size = 0;
00255 a->maxsize = maxsize;
00256 a->maxSizeSoFar = 0;
00257 a->verbose = FALSE;
00258 a->truncationWarning = FALSE;
00259 a->root = a->best = a->worst = -1;
00260 a->freeState = f;
00261 a->nodes = (
TANodeStruct *) memMalloc(
sizeof (
TANodeStruct) * maxsize);
00262 memset(a->nodes, 0, sizeof (TANodeStruct) * maxsize);
00263
00264
for (i = 0; i < maxsize; i++) {
00265 a->nodes[i].parent = i - 1;
00266 }
00267
00268 a->free = maxsize - 1;
00269
00270
return (a);
00271 }
00272
00273
00274
00275
00276
00277
00278 Boolean
taVerbosity(TreeAgenda a)
00279 {
00280
return a->verbose;
00281 }
00282
00283
00284
00285
00286
00287
00288
00289 Boolean
taSetVerbosity(TreeAgenda a, Boolean b)
00290 {
00291 Boolean old = a->verbose;
00292
00293 a->verbose = b;
00294
return (old);
00295 }
00296
00297
00298
00299
00300
00301
00302
00303
00304 int taSize(TreeAgenda a)
00305 {
00306
return (a->size);
00307 }
00308
00309
00310
00311
00312
00313
00314
00315 int taMaxSize(TreeAgenda a)
00316 {
00317
return (a->maxsize);
00318 }
00319
00320
00321
00322
00323
00324
00325
00326 int taMaxSizeSoFar(TreeAgenda a)
00327 {
00328
return (a->maxSizeSoFar);
00329 }
00330
00331
00332
00333
00334
00335
00336
00337 Boolean
taIsEmpty(TreeAgenda a)
00338 {
00339
return (a->size == 0);
00340 }
00341
00342
00343
00344
00345
00346
00347
00348 Boolean
taIsTruncated(TreeAgenda a)
00349 {
00350
return (a->truncationWarning);
00351 }
00352
00353
00354
00355
00356
00357
00358
00359 Boolean
taResetTruncated(TreeAgenda a)
00360 {
00361 Boolean oldTruncationWarning = a->truncationWarning;
00362 a->truncationWarning = FALSE;
00363
return oldTruncationWarning;
00364 }
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379 Boolean
taInsert(TreeAgenda a,
double score, Pointer state)
00380 {
00381
int i, parent,
new, rightmost;
00382 TANode parentnode = NULL, newnode, rightmostnode;
00383 Boolean oldTruncationWarning = a->truncationWarning;
00384
00385
#if TA_DEBUG
00386
if (a->size !=
taCheckNode(a, a->root, TRUE, TRUE)) {
00387 abort();
00388 }
00389
#endif
00390
00391
00392
if (a->size >= a->maxsize) {
00393
00394
if (!a->truncationWarning) {
00395
if (a->verbose) {
00396
00397 }
00398 a->truncationWarning = TRUE;
00399 }
00400
#if TA_DEBUG
00401
00402
for (rightmost = a->root;
00403 a->nodes[rightmost].worse >= 0; rightmost = a->nodes[rightmost].worse) {
00404
00405 }
00406
00407
if (rightmost != a->worst) {
00408 printf(
"DEBUG: rightmost inconsistency\n rightmost ");
00409
taPrintNode(a, rightmost);
00410 printf(
"\n worst ");
00411
taPrintNode(a, a->worst);
00412 printf(
"\n");
00413 }
00414
#else
00415
rightmost = a->worst;
00416
#endif
00417
00418
00419 rightmostnode = &a->nodes[rightmost];
00420
00421
00422
if (score <= rightmostnode->score) {
00423
00424 (*a->freeState) (state);
00425
return (oldTruncationWarning != a->truncationWarning);
00426 }
00427
00428
00429
#if 0
00430
printf(
"WARNING: deleting old state %d with score %4.3f, new one is %4.3f\n",
00431 rightmost, rightmostnode->score, score);
00432
#endif
00433
(*a->freeState) (rightmostnode->state);
00434
if (rightmostnode->parent >= 0) {
00435
00436 a->nodes[rightmostnode->parent].worse = rightmostnode->better;
00437
if (rightmostnode->better >= 0) {
00438 a->nodes[rightmostnode->better].parent = rightmostnode->parent;
00439
for (a->worst = rightmostnode->better;
00440 a->worst >= 0 && a->nodes[a->worst].worse >= 0;
00441 a->worst = a->nodes[a->worst].worse) {
00442
00443 }
00444 }
else {
00445 a->worst = rightmostnode->parent;
00446 }
00447 }
else {
00448
00449
if (rightmostnode->better >= 0) {
00450 a->nodes[rightmostnode->better].parent = -2;
00451 a->root = rightmostnode->better;
00452
for (a->worst = rightmostnode->better;
00453 a->worst >= 0 && a->nodes[a->worst].worse >= 0;
00454 a->worst = a->nodes[a->worst].worse) {
00455
00456 }
00457 }
else {
00458
00459 a->root = -1;
00460 a->worst = -1;
00461 }
00462 }
00463
00464
00465
00466
00467
00468
00469
00470
00471 rightmostnode->parent = -3;
00472 a->free = rightmost;
00473 a->size--;
00474 }
00475
00476
00477 i = a->root;
00478 parent = -4;
00479
while (i >= 0) {
00480 parent = i;
00481 parentnode = &a->nodes[i];
00482
if (score >= parentnode->score) {
00483 i = parentnode->better;
00484 }
else {
00485 i = parentnode->worse;
00486 }
00487 }
00488
00489
00490
00491
00492
00493
00494
new = a->free;
00495 newnode = &a->nodes[
new];
00496 a->free = newnode->parent;
00497 a->size++;
00498 newnode->better = newnode->worse = -1;
00499 newnode->parent = parent;
00500 newnode->score = score;
00501 newnode->state = state;
00502
00503
if (a->root < 0) {
00504
00505 a->root = a->best = a->worst =
new;
00506 }
else {
00507
if (score >= parentnode->score) {
00508 parentnode->better =
new;
00509
if (a->best == parent) {
00510 a->best =
new;
00511 }
00512 }
else {
00513 parentnode->worse =
new;
00514
if (a->worst == parent) {
00515 a->worst =
new;
00516 }
00517 }
00518 }
00519
00520
if (a->maxSizeSoFar < a->size) {
00521 a->maxSizeSoFar = a->size;
00522 }
00523
00524
return (oldTruncationWarning != a->truncationWarning);
00525 }
00526
00527
00528
00529
00530
00531
00532
00533 Pointer
taBest(TreeAgenda a)
00534 {
00535
if (a->best < 0) {
00536
return (NULL);
00537 }
else {
00538
return (a->nodes[a->best].state);
00539 }
00540 }
00541
00542
00543
00544
00545
00546
00547
00548
00549 Pointer
taRemoveBest(TreeAgenda a)
00550 {
00551
int leftmost, parent, rightchild;
00552
00553
#if TA_DEBUG
00554
for (leftmost = a->root;
00555 leftmost >= 0 && a->nodes[leftmost].better >= 0;
00556 leftmost = a->nodes[leftmost].better) {
00557
00558 }
00559
if (leftmost != a->best) {
00560 printf(
"DEBUG: leftmost inconsistency\n leftmost ");
00561
taPrintNode(a, leftmost);
00562 printf(
"\n best ");
00563
taPrintNode(a, a->best);
00564 printf(
"\n size %d root %d\n", a->size, a->root);
00565 }
00566
#else
00567
leftmost = a->best;
00568
#endif
00569
00570
if (leftmost < 0) {
00571 printf(
"ERROR: taRemoveBest: agenda empty (size is %d)\n", a->size);
00572
return (NULL);
00573 }
00574
00575
00576 parent = a->nodes[leftmost].parent;
00577 rightchild = a->nodes[leftmost].worse;
00578
if (parent >= 0) {
00579
00580 a->nodes[parent].better = rightchild;
00581
if (rightchild >= 0) {
00582 a->nodes[rightchild].parent = parent;
00583
for (a->best = rightchild;
00584 a->best >= 0 && a->nodes[a->best].better >= 0;
00585 a->best = a->nodes[a->best].better) {
00586
00587 }
00588 }
else {
00589 a->best = parent;
00590 }
00591 }
else {
00592
00593
if (rightchild >= 0) {
00594 a->nodes[rightchild].parent = -5;
00595 a->root = rightchild;
00596
for (a->best = a->root;
00597 a->best >= 0 && a->nodes[a->best].better >= 0;
00598 a->best = a->nodes[a->best].better) {
00599
00600 }
00601 }
else {
00602
00603
00604
00605
00606 a->root = a->best = a->worst = -1;
00607 }
00608 }
00609
00610 a->nodes[leftmost].parent = a->free;
00611 a->free = leftmost;
00612 a->size--;
00613
00614
return (a->nodes[leftmost].state);
00615 }
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625 void taDelete(TreeAgenda a)
00626 {
00627
int count;
00628
int oldSize;
00629
00630 oldSize = a->size;
00631 count =
taDeleteNode(a, a->root, TRUE);
00632
if (count != oldSize) {
00633 printf(
"WARNING: taDelete, mismatch while deleting %d != %d\n", count,
00634 oldSize);
00635 }
00636
00637 memFree(a->nodes);
00638 memFree(a);
00639 }
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649 TreeAgendaIterator
taIteratorNew(TreeAgenda a)
00650 {
00651 TreeAgendaIterator ai;
00652
00653 ai = (TreeAgendaIterator) memMalloc(
sizeof (
TreeAgendaIteratorStruct));
00654 ai->treeagenda = a;
00655 ai->nextNode = a->best;
00656
return (ai);
00657 }
00658
00659
00660
00661
00662
00663
00664
00665
00666 Pointer
taIteratorNextElement(TreeAgendaIterator ai)
00667 {
00668 Pointer state;
00669
int parent;
00670
00671
if (ai->nextNode < 0) {
00672
return (NULL);
00673 }
00674 state = ai->treeagenda->nodes[ai->nextNode].state;
00675
00676
if (ai->treeagenda->nodes[ai->nextNode].worse >= 0) {
00677
00678
for ( ai->nextNode = ai->treeagenda->nodes[ai->nextNode].worse;
00679 ai->treeagenda->nodes[ai->nextNode].better >= 0;
00680 ai->nextNode = ai->treeagenda->nodes[ai->nextNode].better ) {
00681
00682 }
00683 }
else {
00684 parent = ai->treeagenda->nodes[ai->nextNode].parent;
00685
while (parent >= 0 && ai->nextNode == ai->treeagenda->nodes[parent].worse) {
00686 ai->nextNode = parent;
00687 parent = ai->treeagenda->nodes[ai->nextNode].parent;
00688 }
00689 ai->nextNode = parent;
00690 }
00691
00692
return (state);
00693 }
00694
00695
00696
00697
00698
00699
00700
00701
00702 void taIteratorDelete(TreeAgendaIterator ai)
00703 {
00704 memFree(ai);
00705 }
00706
00707
00708
00709