Generated on Wed Nov 1 15:04:34 2006 for Gecode by doxygen 1.4.5

gcc.cc

Go to the documentation of this file.
00001 /*
00002  *  Main authors:
00003  *     Patrick Pekczynski <pekczynski@ps.uni-sb.de>
00004  *  Copyright:
00005  *     Patrick Pekczynski, 2004
00006  *
00007  *  Last modified:
00008  *     $Date: 2006-08-04 16:03:26 +0200 (Fri, 04 Aug 2006) $ by $Author: schulte $
00009  *     $Revision: 3512 $
00010  *
00011  *  This file is part of Gecode, the generic constraint
00012  *  development environment:
00013  *     http://www.gecode.org
00014  *
00015  *  See the file "LICENSE" for information on usage and
00016  *  redistribution of this file, and for a
00017  *     DISCLAIMER OF ALL WARRANTIES.
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       // check validity
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     // this should be the required min and allowed max
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 //      std::cout << "more occurrences of "<<k[i].card()
00212 //                << " than allowed\n";
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 //      std::cout << "cannot satisfy requiremnts for " << k[i].card() << "!\n";
00222         return ES_FAILED;
00223       }
00224       if (!k[i].assigned()) {
00225         ModEvent me = k[i].lq(home, n);
00226         if (me_failed(me)) {
00227 //        std::cout << "invalid\n";
00228           return ES_FAILED;
00229         }
00230       }
00231     }
00232 
00233 //     std::cout << "mi:" << smin << " x: "<< n << " ma:" << smax<<"\n";
00234     if (n < smin) {
00235 //       std::cout << "not enough variables to satisfy min req\n";
00236       return ES_FAILED;
00237     }
00238 
00239 
00240 //     for (int i = 0; i < k.size(); i++) {
00241 //       std::cout << k[i] << " ";
00242 //     }
00243 
00244 
00245     if (all && smax < n) {
00246 //       std::cout << "the maximal occurrence for the cardinalities cannot be satisfied\n";
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     // mark those values that are specified
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       // value is in a variable domain
00343       if (v >= xmin && indom[v - xmin]) {
00344         if (r < iasize) {
00345           if (v == ia[r]) {
00346             // value is specified with cardinalities
00347             // checking should be outsourced to gcc.cc
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             // value is not specified with cardinalities
00360             // the value is unspecified
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           // there are more values in the variable domains
00369           // than specified
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         // the value is not in a variable domain of the current assignment
00378         if (r < iasize) {
00379           // but it is specified
00380           if (v == ia[r]) {
00381             // checking should be outsourced to gcc.cc
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             // the value is unspecified
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           // there are more values in the variable domains
00402           // than specified
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   // Interfacing gcc with fixed cardinalities
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     // compute number of zero entries
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     // if there are zero entries
00463     if (z > 0) {
00464 
00465       // reduce the occurences
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   // Interfacing gcc with cardinality variables
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     // iterating over cardinality variables
00642     int ci  = 0;
00643     // iterating over the new cardvars
00644     int cvi = 0;
00645     IntVarArgs cv(interval);
00646     for (int i = min; i <= max; i++) {
00647       // value in var domain
00648       if (done[i - min]) {
00649         if (ci < m) {
00650           // specified wih cardinalities
00651           if (i == v[ci]) {
00652             cv[cvi] = c[ci];
00653             ci++;
00654             cvi++;
00655           } else {
00656             // value in domain but unspecified
00657             IntVar iv(home, unspec_low, unspec_up);
00658             cv[cvi] = iv;
00659             cvi++;
00660           }
00661         } else {
00662           // in domain but after the specification
00663           IntVar iv(home, unspec_low, unspec_up);
00664           cv[cvi] = iv;
00665           cvi++;
00666         }
00667       } else {
00668         // not in the variable domain of the current assignment
00669         if (ci < m) {
00670           // but is specified
00671           if (i == v[ci]) {
00672             cv[cvi] = c[ci];
00673             ci++;
00674             cvi++;
00675           } else {
00676             // unspecified and not in x
00677             IntVar iv(home, unspec_low, unspec_up);
00678             cv[cvi] = iv;
00679             cvi++;
00680           }
00681         } else {
00682           // more values than specified
00683           IntVar iv(home, unspec_low, unspec_up);
00684           cv[cvi] = iv;
00685           cvi++;
00686         }
00687       }
00688     }
00689 
00690     if (ci < m) {
00691       // still values left
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 // STATISTICS: int-post