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 namespace Gecode { namespace Int { namespace GCC {
00039
00041
00042
00048 class UnReachable {
00049 public:
00050 unsigned int minb;
00051 unsigned int maxb;
00052 unsigned int eq;
00053 unsigned int le;
00054 unsigned int gr;
00055 };
00056
00061 template <class View, class Card, bool shared>
00062 inline ExecStatus
00063 prop_card(Space& home, ViewArray<View>& x, ViewArray<Card>& k, bool& mod) {
00064 int n = x.size();
00065 int m = k.size();
00066 Region r(home);
00067 UnReachable* rv = r.alloc<UnReachable>(m);
00068 for(int i = m; i--; )
00069 rv[i].minb = rv[i].maxb = rv[i].le = rv[i].gr = rv[i].eq = 0;
00070
00071 for (int i = n; i--; ) {
00072 int b = x[i].assigned();
00073 int min_idx = 0;
00074 int max_idx = 0;
00075 min_idx = lookupValue(k,x[i].min());
00076 if (min_idx == -1) {
00077 return ES_FAILED;
00078 }
00079 if (b) {
00080 rv[min_idx].minb++;
00081 rv[min_idx].maxb++;
00082 rv[min_idx].eq++;
00083 } else {
00084 max_idx = lookupValue(k,x[i].max());
00085 if (max_idx == -1) {
00086 return ES_FAILED;
00087 }
00088
00089
00090 rv[min_idx].minb++;
00091
00092
00093
00094 rv[max_idx].maxb++;
00095 }
00096 }
00097
00098 rv[0].le = 0;
00099 int c_min = 0;
00100 for (int i = 1; i < m; i++) {
00101 rv[i].le = c_min + rv[i - 1].maxb;
00102 c_min += rv[i - 1].maxb;
00103 }
00104
00105 rv[m-1].gr = 0;
00106 int c_max = 0;
00107 for (int i = m-1; i--; ) {
00108 rv[i].gr = c_max + rv[i + 1].minb;
00109 c_max += rv[i + 1].minb;
00110 }
00111
00112 for (int i = m; i--; ) {
00113 int reachable = (int) (x.size() - rv[i].le - rv[i].gr);
00114 if (!k[i].assigned()) {
00115 ModEvent me = k[i].lq(home, reachable);
00116 if (me_failed(me))
00117 return ES_FAILED;
00118 mod |= (me_modified(me) && (k[i].max() != reachable));
00119 mod |= shared && me_modified(me);
00120
00121 if (rv[i].eq > 0) {
00122 ModEvent me = k[i].gq(home, (int) rv[i].eq);
00123 if (me_failed(me))
00124 return ES_FAILED;
00125 mod |= (me_modified(me) && (k[i].min() != (int) rv[i].eq));
00126 mod |= shared && me_modified(me);
00127 }
00128 } else {
00129
00130 int v = k[i].max();
00131 if ( !( (int) rv[i].eq <= v && v <= reachable) )
00132 return ES_FAILED;
00133 }
00134 }
00135
00136 return ES_OK;
00137 }
00138
00139
00143 template <class View, class Card>
00144 inline bool
00145 card_consistent(int& smin, int& smax, ViewArray<View>& x,
00146 ViewArray<Card>& k) {
00147
00148 int m = k.size();
00149 int n = x.size();
00150 for (int i = m; i--; ) {
00151 smax += k[i].max();
00152 smin += k[i].min();
00153 }
00154
00155
00156 if (n < smin) {
00157 return false;
00158 }
00159
00160
00161
00162 if (smax < n) {
00163 return false;
00164 }
00165
00166 return true;
00167 }
00168
00172 class Rank {
00173 public:
00178 int min;
00183 int max;
00184 };
00185
00193 template <class View>
00194 class MaxInc {
00195 protected:
00196 ViewArray<View> x;
00197 public:
00198 MaxInc(const ViewArray<View>& x0) : x(x0) {}
00199 forceinline bool
00200 operator ()(const int i, const int j) {
00201 return x[i].max() < x[j].max();
00202 }
00203 };
00204
00212 template <class View>
00213 class MinInc {
00214 protected:
00215 ViewArray<View> x;
00216 public:
00217 MinInc(const ViewArray<View>& x0) : x(x0) {}
00218 forceinline bool
00219 operator ()(const int i, const int j) {
00220 return x[i].min() < x[j].min();
00221 }
00222 };
00223
00224
00230 template <class Card>
00231 class PartialSum {
00232 private:
00234 char* mem;
00236 size_t _allocated;
00238 int* sum;
00243 int* ds;
00245 int size;
00246 public:
00248
00249 PartialSum( int, int, ViewArray<Card>& , bool);
00250 ~PartialSum(void);
00252
00253
00254 int firstValue;
00255 int lastValue;
00256 int sumup(int, int);
00257 int minValue(void);
00258 int maxValue(void);
00259 int skipNonNullElementsRight(int);
00260 int skipNonNullElementsLeft(int);
00261 void* operator new(size_t s);
00262 void operator delete(void* p);
00263 bool check_update_max(ViewArray<Card>& k);
00264 bool check_update_min(ViewArray<Card>& k);
00265 int getsize(void) const;
00266 size_t allocated(void) const;
00268 };
00269
00271 template <class Card>
00272 forceinline
00273 PartialSum<Card>::~PartialSum(void){
00274 assert(mem != NULL);
00275 heap.rfree(mem);
00276 }
00277
00279 template <class Card>
00280 forceinline void*
00281 PartialSum<Card>::operator new(size_t t){
00282 return heap.ralloc(t);
00283 }
00284
00286 template <class Card>
00287 forceinline void
00288 PartialSum<Card>::operator delete(void* p){
00289 heap.rfree(p);
00290 }
00291
00304 template <class Card>
00305 inline
00306 PartialSum<Card>::PartialSum(int first,
00307 int count,
00308 ViewArray<Card>& elements,
00309 bool up) {
00310 int i = 0;
00311 int j = 0;
00312
00313 size = count + 5;
00314
00315 size_t sum_size = (size) * sizeof(int);
00316 size_t ds_size = (size) * sizeof(int);
00317 size_t total = sum_size + ds_size;
00318 _allocated = total;
00319
00320 mem = static_cast<char*>(heap.ralloc(total));
00321 sum = Support::ptr_cast<int*>(mem);
00322 ds = Support::ptr_cast<int*>(mem + sum_size);
00323
00324 for (int z = 0; z < size; z++) {
00325 sum[z] = 0;
00326 ds[z] = 0;
00327 }
00328
00329
00330
00331
00332
00333
00334 firstValue = first - 3;
00335 lastValue = first + count + 1;
00336
00337
00338
00339 for (i = 3; i--; ){
00340 sum[i] = i;
00341 }
00342
00343 int shift = count + 2;
00344
00345
00346
00347
00348
00349
00350 for (i = 2; i < shift; i++){
00351 if (up) {
00352 sum[i + 1] = sum[i] + elements[i - 2].max();
00353 } else {
00354 sum[i + 1] = sum[i] + elements[i - 2].min();
00355 }
00356 }
00357 sum[i + 1] = sum[i] + 1;
00358 sum[i + 2] = sum[i + 1] + 1;
00359
00360
00361
00362 i = count + 3;
00363 j = i + 1;
00364 for ( ; i > 0; ){
00365 while(sum[i] == sum[i - 1]) {
00366 ds[i] = j;
00367 i--;
00368 }
00369 ds[j] = i;
00370 i--;
00371 j = ds[j];
00372 }
00373 ds[j] = 0;
00374
00375 ds[0] = 0;
00376 }
00377
00381 template <class Card>
00382 forceinline int
00383 PartialSum<Card>::sumup(int from, int to){
00384 if (from <= to) {
00385 return sum[to - firstValue] - sum[from - firstValue - 1];
00386 } else {
00387 return sum[to - firstValue - 1] - sum[from - firstValue];
00388 }
00389 }
00390
00395 template <class Card>
00396 forceinline int
00397 PartialSum<Card>::minValue(void){
00398 return firstValue + 3;
00399 }
00400
00406 template <class Card>
00407 forceinline int
00408 PartialSum<Card>::maxValue(void){
00409 return lastValue - 2;
00410 }
00411
00412
00418 template <class Card>
00419 forceinline int
00420 PartialSum<Card>::skipNonNullElementsRight(int value) {
00421 value -= firstValue;
00422 return (ds[value] < value ? value : ds[value]) + firstValue;
00423 }
00424
00430 template <class Card>
00431 forceinline int
00432 PartialSum<Card>::skipNonNullElementsLeft(int value) {
00433 value -= firstValue;
00434 return (ds[value] > value ? ds[ds[value]] : value) + firstValue;
00435 }
00436
00445 template <class Card>
00446 inline bool
00447 PartialSum<Card>::check_update_max(ViewArray<Card>& k){
00448 if (k.size() <= size - 5) {
00449 return true;
00450 } else {
00451 for (int i = 3; i < size - 2; i++) {
00452 if ((sum[i] - sum[i - 1]) != k[i - 3].max()) {
00453 return true;
00454 }
00455 }
00456 return false;
00457 }
00458 }
00459
00468 template <class Card>
00469 inline bool
00470 PartialSum<Card>::check_update_min(ViewArray<Card>& k){
00471 if (k.size() <= size - 5) {
00472 return true;
00473 } else {
00474 for (int i = 3; i < size - 2; i++) {
00475 if ((sum[i] - sum[i - 1]) != k[i - 3].min()) {
00476 return true;
00477 }
00478 }
00479 return false;
00480 }
00481 }
00482
00484 template <class Card>
00485 forceinline int
00486 PartialSum<Card>::getsize(void) const {
00487 return size;
00488 }
00489 template <class Card>
00490 forceinline size_t
00491 PartialSum<Card>::allocated(void) const {
00492 return sizeof(PartialSum<Card>) + _allocated;
00493 }
00494
00495
00506 class HallInfo {
00507 public:
00509 int bounds;
00515 int t;
00523 int d;
00532 int h;
00537 int s;
00542 int ps;
00549 int newBound;
00550 };
00551
00552
00562
00563 inline void
00564 pathset_ps(HallInfo hall[], int start, int end, int to) {
00565 int k, l;
00566 for (l=start; (k=l) != end; hall[k].ps=to) {
00567 l = hall[k].ps;
00568 }
00569 }
00570
00572 inline void
00573 pathset_s(HallInfo hall[], int start, int end, int to) {
00574 int k, l;
00575 for (l=start; (k=l) != end; hall[k].s=to) {
00576 l = hall[k].s;
00577 }
00578 }
00579
00581 inline void
00582 pathset_t(HallInfo hall[], int start, int end, int to) {
00583 int k, l;
00584 for (l=start; (k=l) != end; hall[k].t=to) {
00585 l = hall[k].t;
00586 }
00587 }
00588
00590 inline void
00591 pathset_h(HallInfo hall[], int start, int end, int to) {
00592 int k, l;
00593 for (l=start; (k=l) != end; hall[k].h=to) {
00594 l = hall[k].h;
00595 }
00596 }
00598
00606
00607 forceinline int
00608 pathmin_h(const HallInfo hall[], int i) {
00609 while (hall[i].h < i)
00610 i = hall[i].h;
00611 return i;
00612 }
00614 forceinline int
00615 pathmin_t(const HallInfo hall[], int i) {
00616 while (hall[i].t < i)
00617 i = hall[i].t;
00618 return i;
00619 }
00621
00628
00629 forceinline int
00630 pathmax_h(const HallInfo hall[], int i) {
00631 while (hall[i].h > i)
00632 i = hall[i].h;
00633 return i;
00634 }
00635
00636
00638 forceinline int
00639 pathmax_t(const HallInfo hall[], int i) {
00640 while (hall[i].t > i) {
00641 i = hall[i].t;
00642 }
00643 return i;
00644 }
00645
00647 forceinline int
00648 pathmax_s(const HallInfo hall[], int i) {
00649 while (hall[i].s > i)
00650 i = hall[i].s;
00651 return i;
00652 }
00653
00655 forceinline int
00656 pathmax_ps(const HallInfo hall[], int i) {
00657 while (hall[i].ps > i)
00658 i = hall[i].ps;
00659 return i;
00660 }
00662
00663
00673 template <class Card>
00674 void
00675 reduce_card(Space& home, int cmin, int cmax, ViewArray<Card>& k) {
00676 if (cmin == cmax) {
00677 int idx = 0;
00678 while (k[idx].card() != cmax) {
00679 idx++;
00680 }
00681 k[0] = k[idx];
00682 k.size(1);
00683 } else {
00684 Region r(home);
00685 bool* zero = r.alloc<bool>(k.size());
00686 int ks = k.size();
00687 int zc = 0;
00688 for (int i = 0; i < ks; i++) {
00689 bool impossible = ( (k[i].counter() == 0) &&
00690 (k[i].card() < cmin ||
00691 k[i].card() > cmax));
00692
00693 if (impossible) {
00694 zero[i] = true;
00695 zc++;
00696 } else {
00697 zero[i] = false;
00698 }
00699 }
00700
00701
00702 if (zero[ks - 1]) {
00703 int m = ks;
00704 while(zero[m - 1]) {
00705 m--;
00706 zc--;
00707 }
00708 k.size(m);
00709 }
00710
00711 if (zc > 0) {
00712 int ks = k.size();
00713
00714 for (int i = 0; i < ks; i++) {
00715 assert(0 <= i && i < ks);
00716 if (zero[i]) {
00717 if (i == ks - 1) {
00718 break;
00719 }
00720
00721
00722
00723 int j = i + 1;
00724 assert(0 <= j && j < ks);
00725 if (j < ks) {
00726 while (zero[j]) {
00727 j++;
00728 }
00729 }
00730 if (j > ks - 1) {
00731 break;
00732 }
00733 k[i] = k[j];
00734 zero[j] = true;
00735 }
00736 }
00737 k.size(ks - zc);
00738 }
00739
00740 }
00741
00742 }
00743
00744 }}}
00745
00746
00747