00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "gecode/int/gcc.hh"
00022
00023 namespace Gecode { namespace Int { namespace GCC {
00024
00035 template<class Card>
00036 forceinline bool
00037 check_alldiff(int n, ViewArray<Card>& k){
00038 int left = 0;
00039 int right = k.size() - 1;
00040 bool alldiff = true;
00041
00042 if (k.size() == 1) {
00043 return (n == 1 && k[0].min() == 1 && k[0].max() == 1);
00044 }
00045 if (n == k.size()) {
00046 while (left < right) {
00047 alldiff &= (k[left].max() == 1 &&
00048 k[left].min() == 1 &&
00049 k[right].max() == 1 &&
00050 k[left].max() == 1);
00051 if (!alldiff) {
00052 break;
00053 }
00054
00055 left++;
00056 right--;
00057 }
00058 } else {
00059 if (n < k.size()) {
00060 while (left < right) {
00061 alldiff &= (k[left].max() == 1 &&
00062 k[left].min() == 0 &&
00063 k[right].max() == 1 &&
00064 k[left].max() == 0);
00065 if (!alldiff) {
00066 break;
00067 }
00068 left++;
00069 right--;
00070 }
00071 } else {
00072 return false;
00073 }
00074 }
00075 return alldiff;
00076 }
00077
00082 template <class View>
00083 forceinline int
00084 x_card(ViewArray<View>& x, IntConLevel icl) {
00085
00086 int n = x.size();
00087
00088 GECODE_AUTOARRAY(ViewRanges<View>, xrange, n);
00089 for (int i = n; i--; ){
00090 ViewRanges<View> iter(x[i]);
00091 xrange[i] = iter;
00092 }
00093
00094 Gecode::Iter::Ranges::NaryUnion<ViewRanges<View> > drl(&xrange[0], x.size());
00095 int r = 0;
00096 if (icl == ICL_BND) {
00097 int fstv = drl.min();
00098 int lstv = 0;
00099 for ( ; drl(); ++drl){
00100 lstv = drl.max();
00101 }
00102 r = lstv - fstv + 1;
00103
00104 } else {
00105
00106 for ( ; drl(); ++drl){
00107 for (int v = drl.min(); v <=drl.max(); v++) {
00108 r ++;
00109 }
00110 }
00111 }
00112 return r;
00113 }
00114
00120 template <class Card, class View>
00121 forceinline void
00122 initcard(Space* home, ViewArray<View>& x, ViewArray<Card>& k,
00123 int lb, int ub,
00124 IntConLevel icl) {
00125 GECODE_AUTOARRAY(ViewRanges<View>, xrange, x.size());
00126 for (int i = x.size(); i--; ){
00127 ViewRanges<View> iter(x[i]);
00128 xrange[i] = iter;
00129 }
00130
00131 Iter::Ranges::NaryUnion<ViewRanges<View> > drl(&xrange[0], x.size());
00132 if (icl == ICL_BND) {
00133 int fstv = drl.min();
00134 int lstv = 0;
00135 for ( ; drl(); ++drl){
00136 lstv = drl.max();
00137 }
00138 for (int i = fstv; i <= lstv; i++) {
00139 k[i - fstv].init(home, lb, ub, i);
00140 }
00141 } else {
00142 int idx = 0;
00143 for ( ; drl(); ++drl){
00144 for (int v = drl.min(); v <= drl.max(); v++){
00145 k[idx].init(home, lb, ub, v);
00146 idx++;
00147 }
00148 }
00149 }
00150 }
00151
00152
00158 template <class Card, class View, bool isView>
00159 forceinline void
00160 setcard(Space* home, ViewArray<View>& x, ViewArray<Card>& k,
00161 int xmin, int xmax) {
00162
00163 int idx = 0;
00164 for (int v = xmin; v <= xmax; v++) {
00165 k[idx].card(v);
00166 k[idx].counter(0);
00167 idx++;
00168 }
00169
00170 bool assigned = true;
00171 for (int i = x.size(); i--; ) {
00172 assigned &= x[i].assigned();
00173 }
00174
00175 if (assigned) {
00176
00177 int size = xmax - (xmin - 1);
00178 GECODE_AUTOARRAY(int, count, size);
00179 for (int i = size; i--; ) {
00180 count[i] = 0;
00181 }
00182 for (int i = x.size(); i--; ) {
00183 count[x[i].val() - xmin]++;
00184 }
00185 for (int i = k.size(); i--; ) {
00186 if (k[i].min() > count[i]) {
00187 home->fail();
00188 }
00189 }
00190 }
00191 }
00192
00193
00201 template<class Card, bool isView>
00202 forceinline ExecStatus
00203 card_cons(Space* home, ViewArray<Card>& k, int n, bool all) {
00204
00205 int smin = 0;
00206 int smax = 0;
00207 int m = k.size();
00208 for (int i = m; i--; ) {
00209 int ci = k[i].counter();
00210 if (ci > k[i].max() ) {
00211
00212
00213 return ES_FAILED;
00214 } else {
00215 smax += (k[i].max() - ci);
00216 if (ci < k[i].min()) {
00217 smin += (k[i].min() - ci);
00218 }
00219 }
00220 if (k[i].min() > n) {
00221
00222 return ES_FAILED;
00223 }
00224 if (!k[i].assigned()) {
00225 ModEvent me = k[i].lq(home, n);
00226 if (me_failed(me)) {
00227
00228 return ES_FAILED;
00229 }
00230 }
00231 }
00232
00233
00234 if (n < smin) {
00235
00236 return ES_FAILED;
00237 }
00238
00239
00240
00241
00242
00243
00244
00245 if (all && smax < n) {
00246
00247 return ES_FAILED;
00248 }
00249
00250 return ES_OK;
00251 }
00252
00258 template<class View, class Card, bool isView>
00259 forceinline void
00260 post_template(Space* home, ViewArray<View>& x, ViewArray<Card>& k,
00261 IntConLevel& icl, bool& all){
00262
00263 int n = x_card(x, icl);
00264 bool rewrite = false;
00265 if (!isView) {
00266 rewrite = check_alldiff(n, k);
00267 }
00268
00269 GECODE_ES_FAIL(home, (card_cons<Card, isView>(home, k, x.size(), all)));
00270 if (!isView && rewrite) {
00271 IntVarArgs xv(x.size());
00272 for (int i = 0; i < x.size(); i++) {
00273 IntVar iv(x[i]);
00274 xv[i] = iv;
00275 }
00276 distinct(home, xv, icl);
00277 } else {
00278 switch (icl) {
00279 case ICL_BND:
00280 GECODE_ES_FAIL(home, (GCC::Bnd<View, Card, isView>::post(home, x, k, all)));
00281 break;
00282 case ICL_DOM:
00283 GECODE_ES_FAIL(home, (GCC::Dom<View, Card, isView>::post(home, x, k, all)));
00284 break;
00285 default:
00286 GECODE_ES_FAIL(home, (GCC::Val<View, Card, isView>::post(home, x, k, all)));
00287 }
00288 }
00289 }
00290
00291 }}
00292
00293 using namespace Int;
00294 using namespace Int::GCC;
00295 using namespace Support;
00296
00297 template <class View>
00298 void initCV(Space* home,
00299 const IntArgs& ia, const ViewArray<View>& x,
00300 int l, ViewArray<OccurBndsView>& a,
00301 int iasize, int val, int nov,
00302 int min, int max,
00303 int unspec_low, int unspec_up) {
00304
00305 int n = x.size();
00306
00307 GECODE_AUTOARRAY(ViewRanges<View>, xrange, n);
00308 for (int i = n; i--; ){
00309 ViewRanges<View> iter(x[i]);
00310 xrange[i] = iter;
00311 }
00312
00313 Gecode::Iter::Ranges::NaryUnion<ViewRanges<View> >
00314 drl(&xrange[0], x.size());
00315 Gecode::Iter::Ranges::Cache<
00316 Gecode::Iter::Ranges::
00317 NaryUnion<ViewRanges<View> > > crl(drl);
00318
00319 int c = 0;
00320 int r = 0;
00321
00322 GECODE_AUTOARRAY(bool, indom, (max - (min - 1)));
00323 for (int i = max - (min - 1); i--; ) {
00324 indom[i] = false;
00325 }
00326 for ( ; crl(); ++crl) {
00327 for (int v = crl.min(); v <= crl.max(); v++) {
00328 indom[v - min] = true;
00329 }
00330 }
00331
00332 int xmin = min;
00333 int xmax = max;
00334
00335 min = std::min(xmin, ia[0]);
00336 max = std::max(xmax, ia[(val - 1) * 3]);
00337
00338 for (int v = min; v <= max; v++) {
00339 if (c > l - 1) {
00340 break;
00341 }
00342
00343 if (v >= xmin && indom[v - xmin]) {
00344 if (r < iasize) {
00345 if (v == ia[r]) {
00346
00347
00348 if (ia[r + 1] > ia[r + 2]) {
00349 throw ArgumentSizeMismatch("Int::gcc");
00350 }
00351
00352 a[c].card(v);
00353 a[c].counter(0);
00354 a[c].min(ia[r + 1]);
00355 a[c].max(ia[r + 2]);
00356 c++;
00357 r += 3;
00358 } else {
00359
00360
00361 a[c].card(v);
00362 a[c].counter(0);
00363 a[c].min(unspec_low);
00364 a[c].max(unspec_up);
00365 c++;
00366 }
00367 } else {
00368
00369
00370 a[c].card(v);
00371 a[c].counter(0);
00372 a[c].min(unspec_low);
00373 a[c].max(unspec_up);
00374 c++;
00375 }
00376 } else {
00377
00378 if (r < iasize) {
00379
00380 if (v == ia[r]) {
00381
00382 if (ia[r + 1] > ia[r + 2]) {
00383 throw ArgumentSizeMismatch("Int::gcc");
00384 }
00385
00386 a[c].card(v);
00387 a[c].counter(0);
00388 a[c].min(ia[r + 1]);
00389 a[c].max(ia[r + 2]);
00390 c++;
00391 r += 3;
00392 } else {
00393
00394 a[c].card(v);
00395 a[c].counter(0);
00396 a[c].min(unspec_low);
00397 a[c].max(unspec_up);
00398 c++;
00399 }
00400 } else {
00401
00402
00403 a[c].card(v);
00404 a[c].counter(0);
00405 a[c].min(unspec_low);
00406 a[c].max(unspec_up);
00407 c++;
00408 }
00409 }
00410 }
00411
00412 if (c < l) {
00413 for ( ; r < iasize; r+=3) {
00414 assert(0 <= c && c < l);
00415 a[c].card(ia[r]);
00416 a[c].counter(0);
00417 a[c].min(unspec_low);
00418 a[c].max(unspec_up);
00419 c++;
00420 r+=3;
00421 }
00422 }
00423 }
00424
00425
00426 void gcc(Space* home, const IntVarArgs& x, const IntArgs& c,
00427 int m, int unspec_low, int unspec_up, int min, int max,
00428 IntConLevel icl) {
00429 if (home->failed()) {
00430 return;
00431 }
00432
00433 ViewArray<IntView> x0(home, x);
00434 if (x0.shared()) {
00435 throw ArgumentSame("Int::GCC");
00436 }
00437
00438
00439 ViewArray<IntView> xv(home, x);
00440
00441 int iasize = m;
00442 int val = m / 3;
00443 int nov = max - (min - 1);
00444
00445 ViewArray<OccurBndsView> cv(home, std::max(nov, val));
00446
00447 initCV(home, c, xv,
00448 std::max(nov, val), cv,
00449 iasize, val, nov,
00450 min, max,
00451 unspec_low, unspec_up);
00452
00453
00454 int z = 0;
00455 for (int j = cv.size(); j--; ){
00456 if (cv[j].max() == 0){
00457 z++;
00458 }
00459 }
00460
00461 bool all = (m == (max) - (min - 1));
00462
00463 if (z > 0) {
00464
00465
00466 ViewArray<OccurBndsView> red(home, cv.size() - z);
00467 IntArgs rem(z);
00468 z = 0;
00469 int c = 0;
00470 int r = red.size() - 1;
00471 for (int j = cv.size(); j--;) {
00472 if (cv[j].max() == 0){
00473 rem[z] = cv[j].card();
00474 z++;
00475 } else {
00476 red[r]= cv[j];
00477 r--;
00478 }
00479 c++;
00480 }
00481
00482 IntSet zero(&rem[0], z);
00483 int n = xv.size();
00484 for (int i = n; i--; ) {
00485 IntSetRanges remzero(zero);
00486 GECODE_ME_FAIL(home, xv[i].minus(home, remzero));
00487 }
00488 GCC::post_template<IntView,OccurBndsView,false>(home, xv, red, icl, all);
00489 } else {
00490 GCC::post_template<IntView,OccurBndsView,false>(home, xv, cv, icl, all);
00491 }
00492 }
00493
00494 void gcc(Space* home, const IntVarArgs& x, const IntArgs& c,
00495 int m, int unspec, int min, int max,
00496 IntConLevel icl) {
00497 gcc(home, x, c, m, 0, unspec, min, max, icl);
00498 }
00499
00500 void gcc(Space* home, const IntVarArgs& x, int lb, int ub,
00501 IntConLevel icl) {
00502 if (home->failed()) {
00503 return;
00504 }
00505
00506 ViewArray<IntView> x0(home, x);
00507 if (x0.shared()) {
00508 throw ArgumentSame("Int::GCC");
00509 }
00510
00511 ViewArray<IntView> xv(home,x);
00512
00513 int values = x_card(xv, icl);
00514
00515 ViewArray<OccurBndsView> c(home, values);
00516 GCC::initcard(home, xv, c, lb, ub, icl);
00517 bool all = true;
00518 GCC::post_template<IntView, OccurBndsView, false>(home, xv, c, icl, all);
00519 }
00520
00521
00522 void gcc(Space* home, const IntVarArgs& x, int ub, IntConLevel icl) {
00523 gcc(home, x, ub, ub, icl);
00524 }
00525
00526
00527
00528 void gcc(Space* home, const IntVarArgs& x, const IntVarArgs& c,
00529 int min, int max, IntConLevel icl) {
00530
00531 if (home->failed()) {
00532 return;
00533 }
00534
00535 ViewArray<IntView> xv(home, x);
00536
00537 linear(home, c, IRT_EQ, xv.size());
00538
00539 ViewArray<CardView> cv(home, c);
00540
00541 int interval = max - min + 1;
00542
00543 GECODE_AUTOARRAY(bool, done, interval);
00544 for (int i = 0; i < interval; i++) {
00545 done[i] = false;
00546 }
00547
00548 GECODE_AUTOARRAY(ViewRanges<IntView>, xrange, xv.size());
00549 for (int i = xv.size(); i--; ){
00550 ViewRanges<IntView> iter(xv[i]);
00551 xrange[i] = iter;
00552 }
00553
00554 Gecode::Iter::Ranges::NaryUnion<ViewRanges<IntView> >
00555 drl(&xrange[0], xv.size());
00556 Gecode::Iter::Ranges::Cache<
00557 Gecode::Iter::Ranges::
00558 NaryUnion<ViewRanges<IntView> > > crl(drl);
00559 for ( ; crl(); ++crl) {
00560 for (int v = crl.min(); v <= crl.max(); v++) {
00561 done[v - min] = true;
00562 }
00563 }
00564
00565 for (int i = 0; i < interval; i++) {
00566 if (!done[i]) {
00567 if (icl == ICL_DOM) {
00568 GECODE_ME_FAIL(home, cv[i].eq(home, 0));
00569 }
00570 }
00571 }
00572
00573 GCC::setcard<CardView, IntView, true>(home, xv, cv, min, max);
00574
00575 int sum_min = 0;
00576 int sum_max = 0;
00577 IntArgs dx(cv.size());
00578 for (int i = 0; i < cv.size(); i++) {
00579 dx[i] = cv[i].card();
00580 sum_min += cv[i].card() * cv[i].min();
00581 sum_max += cv[i].card() * cv[i].max();
00582 }
00583 bool all = true;
00584 GCC::post_template<IntView, CardView, true>(home, xv, cv, icl, all);
00585 }
00586
00587 void gcc(Space* home,
00588 const IntVarArgs& x, const IntArgs& v, const IntVarArgs& c,
00589 int m, int unspec, bool all, int min, int max,
00590 IntConLevel icl) {
00591 gcc(home, x, v, c, m, 0, unspec, all, min, max, icl);
00592 }
00593
00594 void gcc(Space* home,
00595 const IntVarArgs& x, const IntArgs& v, const IntVarArgs& c,
00596 int m, int unspec_low, int unspec_up, bool all, int min, int max,
00597 IntConLevel icl) {
00598
00599 if (m != c.size()) {
00600 throw ArgumentSizeMismatch("Int::gcc");
00601 }
00602 if (home->failed()) {
00603 return;
00604 }
00605
00606 ViewArray<IntView> xv(home, x);
00607
00608 int interval = max - (min - 1);
00609
00610 GECODE_AUTOARRAY(bool, done, interval);
00611 for (int i = 0; i < interval; i++) {
00612 done[i] = false;
00613 }
00614
00615 GECODE_AUTOARRAY(ViewRanges<IntView>, xrange, xv.size());
00616 for (int i = xv.size(); i--; ){
00617 ViewRanges<IntView> iter(xv[i]);
00618 xrange[i] = iter;
00619 }
00620
00621 Gecode::Iter::Ranges::NaryUnion<ViewRanges<IntView> >
00622 drl(&xrange[0], xv.size());
00623 Gecode::Iter::Ranges::Cache<
00624 Gecode::Iter::Ranges::
00625 NaryUnion<ViewRanges<IntView> > > crl(drl);
00626 for ( ; crl(); ++crl) {
00627 for (int v = crl.min(); v <= crl.max(); v++) {
00628 done[v - min] = true;
00629 }
00630 }
00631
00632 if (all) {
00633 linear(home, c, IRT_EQ, xv.size());
00634 for (int i = 0; i < interval; i++) {
00635 done[i] = true;
00636 }
00637 } else {
00638 linear(home, c, IRT_LQ, xv.size());
00639 }
00640
00641
00642 int ci = 0;
00643
00644 int cvi = 0;
00645 IntVarArgs cv(interval);
00646 for (int i = min; i <= max; i++) {
00647
00648 if (done[i - min]) {
00649 if (ci < m) {
00650
00651 if (i == v[ci]) {
00652 cv[cvi] = c[ci];
00653 ci++;
00654 cvi++;
00655 } else {
00656
00657 IntVar iv(home, unspec_low, unspec_up);
00658 cv[cvi] = iv;
00659 cvi++;
00660 }
00661 } else {
00662
00663 IntVar iv(home, unspec_low, unspec_up);
00664 cv[cvi] = iv;
00665 cvi++;
00666 }
00667 } else {
00668
00669 if (ci < m) {
00670
00671 if (i == v[ci]) {
00672 cv[cvi] = c[ci];
00673 ci++;
00674 cvi++;
00675 } else {
00676
00677 IntVar iv(home, unspec_low, unspec_up);
00678 cv[cvi] = iv;
00679 cvi++;
00680 }
00681 } else {
00682
00683 IntVar iv(home, unspec_low, unspec_up);
00684 cv[cvi] = iv;
00685 cvi++;
00686 }
00687 }
00688 }
00689
00690 if (ci < m) {
00691
00692 for (; ci < m; ci++) {
00693 cv[cvi] = c[ci];
00694 ci++;
00695 cvi++;
00696 }
00697 }
00698
00699
00700 ViewArray<CardView> cardv(home, cv);
00701
00702 GCC::setcard<CardView, IntView, true>(home, xv, cardv, min, max);
00703 GCC::post_template<IntView, CardView, true>(home, xv, cardv, icl, all);
00704 }
00705 }
00706
00707
00708