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 GECODE_AUTOARRAY(UnReachable, rv, m);
00067 for(int i = m; i--; ) {
00068 rv[i].minb = 0;
00069 rv[i].maxb = 0;
00070 rv[i].le = 0;
00071 rv[i].gr = 0;
00072 rv[i].eq = 0;
00073 }
00074
00075 for (int i = n; i--; ) {
00076 int b = x[i].assigned();
00077 int min_idx = 0;
00078 int max_idx = 0;
00079 min_idx = lookupValue(k,x[i].min());
00080 if (min_idx == -1) {
00081 return ES_FAILED;
00082 }
00083 if (b) {
00084 rv[min_idx].minb++;
00085 rv[min_idx].maxb++;
00086 rv[min_idx].eq++;
00087 } else {
00088 max_idx = lookupValue(k,x[i].max());
00089 if (max_idx == -1) {
00090 return ES_FAILED;
00091 }
00092
00093
00094 rv[min_idx].minb++;
00095
00096
00097
00098 rv[max_idx].maxb++;
00099 }
00100 }
00101
00102 rv[0].le = 0;
00103 int c_min = 0;
00104 for (int i = 1; i < m; i++) {
00105 rv[i].le = c_min + rv[i - 1].maxb;
00106 c_min += rv[i - 1].maxb;
00107 }
00108
00109 rv[m-1].gr = 0;
00110 int c_max = 0;
00111 for (int i = m-1; i--; ) {
00112 rv[i].gr = c_max + rv[i + 1].minb;
00113 c_max += rv[i + 1].minb;
00114 }
00115
00116 for (int i = m; i--; ) {
00117 int reachable = (int) (x.size() - rv[i].le - rv[i].gr);
00118 if (!k[i].assigned()) {
00119 ModEvent me = k[i].lq(home, reachable);
00120 if (me_failed(me))
00121 return ES_FAILED;
00122 mod |= (me_modified(me) && (k[i].max() != reachable));
00123 mod |= shared && me_modified(me);
00124
00125 if (rv[i].eq > 0) {
00126 ModEvent me = k[i].gq(home, (int) rv[i].eq);
00127 if (me_failed(me))
00128 return ES_FAILED;
00129 mod |= (me_modified(me) && (k[i].min() != (int) rv[i].eq));
00130 mod |= shared && me_modified(me);
00131 }
00132 } else {
00133
00134 int v = k[i].max();
00135 if ( !( (int) rv[i].eq <= v && v <= reachable) )
00136 return ES_FAILED;
00137 }
00138 }
00139
00140 return ES_OK;
00141 }
00142
00143
00147 template <class View, class Card>
00148 inline bool
00149 card_consistent(int& smin, int& smax, ViewArray<View>& x,
00150 ViewArray<Card>& k) {
00151
00152 int m = k.size();
00153 int n = x.size();
00154 for (int i = m; i--; ) {
00155 smax += k[i].max();
00156 smin += k[i].min();
00157 }
00158
00159
00160 if (n < smin) {
00161 return false;
00162 }
00163
00164
00165
00166 if (smax < n) {
00167 return false;
00168 }
00169
00170 return true;
00171 }
00172
00176 class Rank {
00177 public:
00182 int min;
00187 int max;
00188 };
00189
00197 template <class View>
00198 class MaxInc {
00199 protected:
00200 ViewArray<View> x;
00201 public:
00202 MaxInc(const ViewArray<View>& x0) : x(x0) {}
00203 forceinline bool
00204 operator()(const int i, const int j) {
00205 return x[i].max() < x[j].max();
00206 }
00207 };
00208
00216 template <class View>
00217 class MinInc {
00218 protected:
00219 ViewArray<View> x;
00220 public:
00221 MinInc(const ViewArray<View>& x0) : x(x0) {}
00222 forceinline bool
00223 operator()(const int i, const int j) {
00224 return x[i].min() < x[j].min();
00225 }
00226 };
00227
00228
00234 template <class Card>
00235 class PartialSum {
00236 private:
00238 char* mem;
00240 size_t _allocated;
00242 int* sum;
00247 int* ds;
00249 int size;
00250 public:
00252
00253 PartialSum( int, int, ViewArray<Card>& , bool);
00254 ~PartialSum(void);
00256
00257
00258 int firstValue;
00259 int lastValue;
00260 int sumup(int, int);
00261 int minValue(void);
00262 int maxValue(void);
00263 int skipNonNullElementsRight(int);
00264 int skipNonNullElementsLeft(int);
00265 void* operator new(size_t s);
00266 void operator delete(void* p);
00267 void print(void);
00268 bool check_update_max(ViewArray<Card>& k);
00269 bool check_update_min(ViewArray<Card>& k);
00270 int getsize(void) const;
00271 size_t allocated(void) const;
00273 };
00274
00276 template <class Card>
00277 forceinline
00278 PartialSum<Card>::~PartialSum(void){
00279 assert(mem != NULL);
00280 Memory::free(mem);
00281 }
00282
00284 template <class Card>
00285 forceinline void*
00286 PartialSum<Card>::operator new(size_t t){
00287 return Memory::malloc(t);
00288 }
00289
00291 template <class Card>
00292 forceinline void
00293 PartialSum<Card>::operator delete(void* p){
00294 Memory::free(p);
00295 }
00296
00309 template <class Card>
00310 inline
00311 PartialSum<Card>::PartialSum(int first,
00312 int count,
00313 ViewArray<Card>& elements,
00314 bool up) {
00315 int i = 0;
00316 int j = 0;
00317
00318 size = count + 5;
00319
00320 size_t sum_size = (size) * sizeof(int);
00321 size_t ds_size = (size) * sizeof(int);
00322 size_t total = sum_size + ds_size;
00323 _allocated = total;
00324
00325 mem = static_cast<char*>(Memory::malloc(total));
00326 sum = Support::ptr_cast<int*>(mem);
00327 ds = Support::ptr_cast<int*>(mem + sum_size);
00328
00329 for (int z = 0; z < size; z++) {
00330 sum[z] = 0;
00331 ds[z] = 0;
00332 }
00333
00334
00335
00336
00337
00338
00339 firstValue = first - 3;
00340 lastValue = first + count + 1;
00341
00342
00343
00344 for (i = 3; i--; ){
00345 sum[i] = i;
00346 }
00347
00348 int shift = count + 2;
00349
00350
00351
00352
00353
00354
00355 for (i = 2; i < shift; i++){
00356 if (up) {
00357 sum[i + 1] = sum[i] + elements[i - 2].max();
00358 } else {
00359 sum[i + 1] = sum[i] + elements[i - 2].min();
00360 }
00361 }
00362 sum[i + 1] = sum[i] + 1;
00363 sum[i + 2] = sum[i + 1] + 1;
00364
00365
00366
00367 i = count + 3;
00368 j = i + 1;
00369 for ( ; i > 0; ){
00370 while(sum[i] == sum[i - 1]) {
00371 ds[i] = j;
00372 i--;
00373 }
00374 ds[j] = i;
00375 i--;
00376 j = ds[j];
00377 }
00378 ds[j] = 0;
00379
00380 ds[0] = 0;
00381 }
00382
00386 template <class Card>
00387 forceinline int
00388 PartialSum<Card>::sumup(int from, int to){
00389 if (from <= to) {
00390 return sum[to - firstValue] - sum[from - firstValue - 1];
00391 } else {
00392 return sum[to - firstValue - 1] - sum[from - firstValue];
00393 }
00394 }
00395
00400 template <class Card>
00401 forceinline int
00402 PartialSum<Card>::minValue(void){
00403 return firstValue + 3;
00404 }
00405
00411 template <class Card>
00412 forceinline int
00413 PartialSum<Card>::maxValue(void){
00414 return lastValue - 2;
00415 }
00416
00417
00423 template <class Card>
00424 forceinline int
00425 PartialSum<Card>::skipNonNullElementsRight(int value) {
00426 value -= firstValue;
00427 return (ds[value] < value ? value : ds[value]) + firstValue;
00428 }
00429
00435 template <class Card>
00436 forceinline int
00437 PartialSum<Card>::skipNonNullElementsLeft(int value) {
00438 value -= firstValue;
00439 return (ds[value] > value ? ds[ds[value]] : value) + firstValue;
00440 }
00441
00443 template <class Card>
00444 void
00445 PartialSum<Card>::print(void){
00446 std::cout << "----------\n";
00447 std::cout << "smallest elem = "<< minValue() << " - "
00448 << "largest elem = "<< maxValue() << "\n";
00449 std::cout << "fsv: "<< firstValue <<" lsv: " << lastValue
00450 << " size = "<< size << "\n";
00451 std::cout << "number of elements = "<< size - 5<<"\n";
00452 std::cout << "elements: ";
00453 for (int i = 3; i < size - 2; i++) {
00454 std::cout << sum[i] - sum[i-1] << " ";
00455 }
00456 std::cout <<"\n";
00457
00458 std::cout << "sum: ";
00459 for (int i = 0; i < size; i++) {
00460 std::cout <<sum[i] << " ";
00461 }
00462 std::cout <<"\n";
00463 std::cout << "ds: ";
00464 for (int i = 0; i < size; i++) {
00465 std::cout <<sum[i] << " ";
00466 }
00467 std::cout <<"\n";
00468
00469 }
00470
00479 template <class Card>
00480 inline bool
00481 PartialSum<Card>::check_update_max(ViewArray<Card>& k){
00482 if (k.size() <= size - 5) {
00483 return true;
00484 } else {
00485 for (int i = 3; i < size - 2; i++) {
00486 if ((sum[i] - sum[i - 1]) != k[i - 3].max()) {
00487 return true;
00488 }
00489 }
00490 return false;
00491 }
00492 }
00493
00502 template <class Card>
00503 inline bool
00504 PartialSum<Card>::check_update_min(ViewArray<Card>& k){
00505 if (k.size() <= size - 5) {
00506 return true;
00507 } else {
00508 for (int i = 3; i < size - 2; i++) {
00509 if ((sum[i] - sum[i - 1]) != k[i - 3].min()) {
00510 return true;
00511 }
00512 }
00513 return false;
00514 }
00515 }
00516
00518 template <class Card>
00519 forceinline int
00520 PartialSum<Card>::getsize(void) const {
00521 return size;
00522 }
00523 template <class Card>
00524 forceinline size_t
00525 PartialSum<Card>::allocated(void) const {
00526 return sizeof(PartialSum<Card>) + _allocated;
00527 }
00528
00529
00540 class HallInfo {
00541 public:
00543 int bounds;
00549 int t;
00557 int d;
00566 int h;
00571 int s;
00576 int ps;
00583 int newBound;
00584 };
00585
00586
00596
00597 inline void
00598 pathset_ps(HallInfo hall[], int start, int end, int to) {
00599 int k, l;
00600 for (l=start; (k=l) != end; hall[k].ps=to) {
00601 l = hall[k].ps;
00602 }
00603 }
00604
00606 inline void
00607 pathset_s(HallInfo hall[], int start, int end, int to) {
00608 int k, l;
00609 for (l=start; (k=l) != end; hall[k].s=to) {
00610 l = hall[k].s;
00611 }
00612 }
00613
00615 inline void
00616 pathset_t(HallInfo hall[], int start, int end, int to) {
00617 int k, l;
00618 for (l=start; (k=l) != end; hall[k].t=to) {
00619 l = hall[k].t;
00620 }
00621 }
00622
00624 inline void
00625 pathset_h(HallInfo hall[], int start, int end, int to) {
00626 int k, l;
00627 for (l=start; (k=l) != end; hall[k].h=to) {
00628 l = hall[k].h;
00629 }
00630 }
00632
00640
00641 forceinline int
00642 pathmin_h(const HallInfo hall[], int i) {
00643 while (hall[i].h < i)
00644 i = hall[i].h;
00645 return i;
00646 }
00648 forceinline int
00649 pathmin_t(const HallInfo hall[], int i) {
00650 while (hall[i].t < i)
00651 i = hall[i].t;
00652 return i;
00653 }
00655
00662
00663 forceinline int
00664 pathmax_h(const HallInfo hall[], int i) {
00665 while (hall[i].h > i)
00666 i = hall[i].h;
00667 return i;
00668 }
00669
00670
00672 forceinline int
00673 pathmax_t(const HallInfo hall[], int i) {
00674 while (hall[i].t > i) {
00675 i = hall[i].t;
00676 }
00677 return i;
00678 }
00679
00681 forceinline int
00682 pathmax_s(const HallInfo hall[], int i) {
00683 while (hall[i].s > i)
00684 i = hall[i].s;
00685 return i;
00686 }
00687
00689 forceinline int
00690 pathmax_ps(const HallInfo hall[], int i) {
00691 while (hall[i].ps > i)
00692 i = hall[i].ps;
00693 return i;
00694 }
00696
00697
00707 template <class Card>
00708 void
00709 reduce_card(int cmin, int cmax, ViewArray<Card>& k) {
00710 if (cmin == cmax) {
00711 int idx = 0;
00712 while (k[idx].card() != cmax) {
00713 idx++;
00714 }
00715 k[0] = k[idx];
00716 k.size(1);
00717 } else {
00718 GECODE_AUTOARRAY(bool, zero, k.size());
00719 int ks = k.size();
00720 int zc = 0;
00721 for (int i = 0; i < ks; i++) {
00722 bool impossible = ( (k[i].counter() == 0) &&
00723 (k[i].card() < cmin ||
00724 k[i].card() > cmax));
00725
00726 if (impossible) {
00727 zero[i] = true;
00728 zc++;
00729 } else {
00730 zero[i] = false;
00731 }
00732 }
00733
00734
00735 if (zero[ks - 1]) {
00736 int m = ks;
00737 while(zero[m - 1]) {
00738 m--;
00739 zc--;
00740 }
00741 k.size(m);
00742 }
00743
00744 if (zc > 0) {
00745 int ks = k.size();
00746
00747 for (int i = 0; i < ks; i++) {
00748 assert(0 <= i && i < ks);
00749 if (zero[i]) {
00750 if (i == ks - 1) {
00751 break;
00752 }
00753
00754
00755
00756 int j = i + 1;
00757 assert(0 <= j && j < ks);
00758 if (j < ks) {
00759 while (zero[j]) {
00760 j++;
00761 }
00762 }
00763 if (j > ks - 1) {
00764 break;
00765 }
00766 k[i] = k[j];
00767 zero[j] = true;
00768 }
00769 }
00770 k.size(ks - zc);
00771 }
00772
00773 }
00774
00775 }
00776
00777 }}}
00778
00779
00780