00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 namespace Gecode { namespace Int { namespace GCC {
00023
00025
00026
00032 class UnReachable {
00033 public:
00034 unsigned int minb;
00035 unsigned int maxb;
00036 unsigned int eq;
00037 unsigned int le;
00038 unsigned int gr;
00039 };
00040
00045 template <class View, class Card, bool shared>
00046 forceinline ExecStatus
00047 prop_card(Space* home, ViewArray<View>& x, ViewArray<Card>& k, bool& mod) {
00048 int n = x.size();
00049 int m = k.size();
00050 GECODE_AUTOARRAY(UnReachable, rv, m);
00051 for(int i = m; i--; ) {
00052 rv[i].minb = 0;
00053 rv[i].maxb = 0;
00054 rv[i].le = 0;
00055 rv[i].gr = 0;
00056 rv[i].eq = 0;
00057 }
00058
00059 for (int i = n; i--; ) {
00060 int b = x[i].assigned();
00061 int min_idx = 0;
00062 int max_idx = 0;
00063 min_idx = lookupValue(k,x[i].min());
00064 if (min_idx == -1) {
00065 return ES_FAILED;
00066 }
00067 if (b) {
00068 rv[min_idx].minb++;
00069 rv[min_idx].maxb++;
00070 rv[min_idx].eq++;
00071 } else {
00072 max_idx = lookupValue(k,x[i].max());
00073 if (max_idx == -1) {
00074 return ES_FAILED;
00075 }
00076
00077
00078 rv[min_idx].minb++;
00079
00080
00081
00082 rv[max_idx].maxb++;
00083 }
00084 }
00085
00086 rv[0].le = 0;
00087 int c_min = 0;
00088 for (int i = 1; i < m; i++) {
00089 rv[i].le = c_min + rv[i - 1].maxb;
00090 c_min += rv[i - 1].maxb;
00091 }
00092
00093 rv[m-1].gr = 0;
00094 int c_max = 0;
00095 for (int i = m-1; i--; ) {
00096 rv[i].gr = c_max + rv[i + 1].minb;
00097 c_max += rv[i + 1].minb;
00098 }
00099
00100 for (int i = m; i--; ) {
00101 int reachable = (int) (x.size() - rv[i].le - rv[i].gr);
00102 if (!k[i].assigned()) {
00103 ModEvent me = k[i].lq(home, reachable);
00104 if (me_failed(me)) {
00105 return ES_FAILED;
00106 }
00107 mod |= (k[i].modified() && (k[i].max() != reachable));
00108 mod |= shared && k[i].modified();
00109
00110 if (rv[i].eq > 0) {
00111 ModEvent me = k[i].gq(home, (int) rv[i].eq);
00112 if (me_failed(me)) {
00113 return ES_FAILED;
00114 }
00115 mod |= (k[i].modified() && (k[i].min() != (int) rv[i].eq));
00116 mod |= shared && k[i].modified();
00117 }
00118 } else {
00119
00120 int v = k[i].max();
00121 if ( !( (int) rv[i].eq <= v && v <= reachable) ) {
00122 return ES_FAILED;
00123 }
00124 }
00125 }
00126
00127 return ES_OK;
00128 }
00129
00130
00134 template <class View, class Card>
00135 inline bool
00136 card_consistent(int& smin, int& smax, ViewArray<View>& x,
00137 ViewArray<Card>& k, bool& all) {
00138
00139 int m = k.size();
00140 int n = x.size();
00141 for (int i = m; i--; ) {
00142 smax += k[i].max();
00143 smin += k[i].min();
00144 }
00145
00146
00147 if (n < smin) {
00148 return false;
00149 }
00150
00151
00152
00153 if (all && smax < n) {
00154 return false;
00155 }
00156
00157 return true;
00158 }
00159
00163 class Rank {
00164 public:
00169 int min;
00174 int max;
00175 };
00176
00184 template <class View>
00185 class MaxInc {
00186 protected:
00187 ViewArray<View> x;
00188 public:
00189 MaxInc(const ViewArray<View>& x0) : x(x0) {}
00190 forceinline bool
00191 operator()(const int i, const int j) {
00192 return x[i].max() < x[j].max();
00193 }
00194 };
00195
00203 template <class View>
00204 class MinInc {
00205 protected:
00206 ViewArray<View> x;
00207 public:
00208 MinInc(const ViewArray<View>& x0) : x(x0) {}
00209 forceinline bool
00210 operator()(const int i, const int j) {
00211 return x[i].min() < x[j].min();
00212 }
00213 };
00214
00215
00221 template <class Card>
00222 class PartialSum {
00223 private:
00225 char* mem;
00227 int* sum;
00232 int* ds;
00234 int size;
00235 public:
00237
00238 PartialSum( int, int, ViewArray<Card>& , bool);
00239 ~PartialSum(void);
00241
00242
00243 int firstValue;
00244 int lastValue;
00245 int sumup(int, int);
00246 int minValue(void);
00247 int maxValue(void);
00248 int skipNonNullElementsRight(int);
00249 int skipNonNullElementsLeft(int);
00250 void* operator new(size_t s);
00251 void operator delete(void* p);
00252 void print(void);
00253 bool check_update_max(ViewArray<Card>& k);
00254 bool check_update_min(ViewArray<Card>& k);
00255 int getsize(void);
00257 };
00258
00260 template <class Card>
00261 forceinline
00262 PartialSum<Card>::~PartialSum(void){
00263 assert(mem != NULL);
00264 Memory::free(mem);
00265 }
00266
00268 template <class Card>
00269 forceinline void*
00270 PartialSum<Card>::operator new(size_t t){
00271 void* allocated = Memory::malloc(t);
00272 return allocated;
00273 }
00274
00276 template <class Card>
00277 forceinline void
00278 PartialSum<Card>::operator delete(void* p){
00279 Memory::free(p);
00280 }
00281
00294 template <class Card>
00295 inline
00296 PartialSum<Card>::PartialSum(int first,
00297 int count,
00298 ViewArray<Card>& elements,
00299 bool up) {
00300 int i = 0;
00301 int j = 0;
00302
00303 size = count + 5;
00304
00305 size_t sum_size = (size) * sizeof(int);
00306 size_t ds_size = (size) * sizeof(int);
00307 size_t total = sum_size + ds_size;
00308
00309 mem = reinterpret_cast<char*> (Memory::malloc(total));
00310 sum = reinterpret_cast<int*> (mem);
00311 ds = reinterpret_cast<int*> (mem + sum_size);
00312
00313 for (int z = 0; z < size; z++) {
00314 sum[z] = 0;
00315 ds[z] = 0;
00316 }
00317
00318
00319
00320
00321
00322
00323 firstValue = first - 3;
00324 lastValue = first + count + 1;
00325
00326
00327
00328 for (i = 3; i--; ){
00329 sum[i] = i;
00330 }
00331
00332 int shift = count + 2;
00333
00334
00335
00336
00337
00338
00339 for (i = 2; i < shift; i++){
00340 if (up) {
00341 sum[i + 1] = sum[i] + elements[i - 2].max();
00342 } else {
00343 sum[i + 1] = sum[i] + elements[i - 2].min();
00344 }
00345 }
00346 sum[i + 1] = sum[i] + 1;
00347 sum[i + 2] = sum[i + 1] + 1;
00348
00349
00350
00351 i = count + 3;
00352 j = i + 1;
00353 for ( ; i > 0; ){
00354 while(sum[i] == sum[i - 1]) {
00355 ds[i] = j;
00356 i--;
00357 }
00358 ds[j] = i;
00359 i--;
00360 j = ds[j];
00361 }
00362 ds[j] = 0;
00363
00364 ds[0] = 0;
00365 }
00366
00370 template <class Card>
00371 forceinline int
00372 PartialSum<Card>::sumup(int from, int to){
00373 if (from <= to) {
00374 return sum[to - firstValue] - sum[from - firstValue - 1];
00375 } else {
00376 return sum[to - firstValue - 1] - sum[from - firstValue];
00377 }
00378 }
00379
00384 template <class Card>
00385 forceinline int
00386 PartialSum<Card>::minValue(void){
00387 return firstValue + 3;
00388 }
00389
00395 template <class Card>
00396 forceinline int
00397 PartialSum<Card>::maxValue(void){
00398 return lastValue - 2;
00399 }
00400
00401
00407 template <class Card>
00408 forceinline int
00409 PartialSum<Card>::skipNonNullElementsRight(int value) {
00410 value -= firstValue;
00411 return (ds[value] < value ? value : ds[value]) + firstValue;
00412 }
00413
00419 template <class Card>
00420 forceinline int
00421 PartialSum<Card>::skipNonNullElementsLeft(int value) {
00422 value -= firstValue;
00423 return (ds[value] > value ? ds[ds[value]] : value) + firstValue;
00424 }
00425
00427 template <class Card>
00428 void
00429 PartialSum<Card>::print(void){
00430 std::cout << "----------\n";
00431 std::cout << "smallest elem = "<< minValue() << " - "
00432 << "largest elem = "<< maxValue() << "\n";
00433 std::cout << "fsv: "<< firstValue <<" lsv: " << lastValue
00434 << " size = "<< size << "\n";
00435 std::cout << "number of elements = "<< size - 5<<"\n";
00436 std::cout << "elements: ";
00437 for (int i = 3; i < size - 2; i++) {
00438 std::cout << sum[i] - sum[i-1] << " ";
00439 }
00440 std::cout <<"\n";
00441
00442 std::cout << "sum: ";
00443 for (int i = 0; i < size; i++) {
00444 std::cout <<sum[i] << " ";
00445 }
00446 std::cout <<"\n";
00447 std::cout << "ds: ";
00448 for (int i = 0; i < size; i++) {
00449 std::cout <<sum[i] << " ";
00450 }
00451 std::cout <<"\n";
00452
00453 }
00454
00463 template <class Card>
00464 inline bool
00465 PartialSum<Card>::check_update_max(ViewArray<Card>& k){
00466 if (k.size() <= size - 5) {
00467 return true;
00468 } else {
00469 for (int i = 3; i < size - 2; i++) {
00470 if ((sum[i] - sum[i - 1]) != k[i - 3].max()) {
00471 return true;
00472 }
00473 }
00474 return false;
00475 }
00476 }
00477
00486 template <class Card>
00487 inline bool
00488 PartialSum<Card>::check_update_min(ViewArray<Card>& k){
00489 if (k.size() <= size - 5) {
00490 return true;
00491 } else {
00492 for (int i = 3; i < size - 2; i++) {
00493 if ((sum[i] - sum[i - 1]) != k[i - 3].min()) {
00494 return true;
00495 }
00496 }
00497 return false;
00498 }
00499 }
00500
00502 template <class Card>
00503 forceinline int
00504 PartialSum<Card>::getsize(void){
00505 return size;
00506 }
00507
00508
00519 class HallInfo {
00520 public:
00522 int bounds;
00528 int t;
00536 int d;
00545 int h;
00550 int s;
00555 int ps;
00562 int newBound;
00563 };
00564
00565
00575
00576 inline void
00577 pathset_ps(HallInfo hall[], int start, int end, int to) {
00578 int k, l;
00579 for (l=start; (k=l) != end; hall[k].ps=to) {
00580 l = hall[k].ps;
00581 }
00582 }
00583
00585 inline void
00586 pathset_s(HallInfo hall[], int start, int end, int to) {
00587 int k, l;
00588 for (l=start; (k=l) != end; hall[k].s=to) {
00589 l = hall[k].s;
00590 }
00591 }
00592
00594 inline void
00595 pathset_t(HallInfo hall[], int start, int end, int to) {
00596 int k, l;
00597 for (l=start; (k=l) != end; hall[k].t=to) {
00598 l = hall[k].t;
00599 }
00600 }
00601
00603 inline void
00604 pathset_h(HallInfo hall[], int start, int end, int to) {
00605 int k, l;
00606 for (l=start; (k=l) != end; hall[k].h=to) {
00607 l = hall[k].h;
00608 }
00609 }
00611
00619
00620 forceinline int
00621 pathmin_h(const HallInfo hall[], int i) {
00622 while (hall[i].h < i)
00623 i = hall[i].h;
00624 return i;
00625 }
00627 forceinline int
00628 pathmin_t(const HallInfo hall[], int i) {
00629 while (hall[i].t < i)
00630 i = hall[i].t;
00631 return i;
00632 }
00634
00641
00642 forceinline int
00643 pathmax_h(const HallInfo hall[], int i) {
00644 while (hall[i].h > i)
00645 i = hall[i].h;
00646 return i;
00647 }
00648
00649
00651 forceinline int
00652 pathmax_t(const HallInfo hall[], int i) {
00653 while (hall[i].t > i) {
00654 i = hall[i].t;
00655 }
00656 return i;
00657 }
00658
00660 forceinline int
00661 pathmax_s(const HallInfo hall[], int i) {
00662 while (hall[i].s > i)
00663 i = hall[i].s;
00664 return i;
00665 }
00666
00668 forceinline int
00669 pathmax_ps(const HallInfo hall[], int i) {
00670 while (hall[i].ps > i)
00671 i = hall[i].ps;
00672 return i;
00673 }
00675
00676
00686 template <class Card>
00687 void
00688 reduce_card(int cmin, int cmax, ViewArray<Card>& k) {
00689 if (cmin == cmax) {
00690 int idx = 0;
00691 while (k[idx].card() != cmax) {
00692 idx++;
00693 }
00694 k[0] = k[idx];
00695 k.size(1);
00696 } else {
00697
00698 GECODE_AUTOARRAY(bool, zero, k.size());
00699 int ks = k.size();
00700 int zc = 0;
00701 for (int i = 0; i < ks; i++) {
00702 bool impossible = ( (k[i].counter() == 0) &&
00703 (k[i].card() < cmin ||
00704 k[i].card() > cmax));
00705
00706 if (impossible) {
00707 zero[i] = true;
00708 zc++;
00709 } else {
00710 zero[i] = false;
00711 }
00712 }
00713
00714
00715 if (zero[ks - 1]) {
00716 int m = ks;
00717 while(zero[m - 1]) {
00718 m--;
00719 zc--;
00720 }
00721 k.size(m);
00722 }
00723
00724 if (zc > 0) {
00725 int ks = k.size();
00726
00727 for (int i = 0; i < ks; i++) {
00728 assert(0 <= i && i < ks);
00729 if (zero[i]) {
00730 if (i == ks - 1) {
00731 break;
00732 }
00733
00734
00735
00736 int j = i + 1;
00737 assert(0 <= j && j < ks);
00738 if (j < ks) {
00739 while (zero[j]) {
00740 j++;
00741 }
00742 }
00743 if (j > ks - 1) {
00744 break;
00745 }
00746 k[i] = k[j];
00747 zero[j] = true;
00748 }
00749 }
00750 k.size(ks - zc);
00751 }
00752
00753 }
00754
00755 }
00756
00757 }}}
00758
00759
00760