Generated on Mon Jul 6 18:09:09 2009 for Gecode by doxygen 1.5.9

gcc.cpp

Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
00002 /*
00003  *  Main authors:
00004  *     Patrick Pekczynski <pekczynski@ps.uni-sb.de>
00005  *     Guido Tack <tack@gecode.org>
00006  *
00007  *  Copyright:
00008  *     Patrick Pekczynski, 2004
00009  *     Guido Tack, 2006
00010  *
00011  *  Last modified:
00012  *     $Date: 2009-02-24 13:58:02 +0100 (Tue, 24 Feb 2009) $ by $Author: schulte $
00013  *     $Revision: 8279 $
00014  *
00015  *  This file is part of Gecode, the generic constraint
00016  *  development environment:
00017  *     http://www.gecode.org
00018  *
00019  *  Permission is hereby granted, free of charge, to any person obtaining
00020  *  a copy of this software and associated documentation files (the
00021  *  "Software"), to deal in the Software without restriction, including
00022  *  without limitation the rights to use, copy, modify, merge, publish,
00023  *  distribute, sublicense, and/or sell copies of the Software, and to
00024  *  permit persons to whom the Software is furnished to do so, subject to
00025  *  the following conditions:
00026  *
00027  *  The above copyright notice and this permission notice shall be
00028  *  included in all copies or substantial portions of the Software.
00029  *
00030  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00031  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00032  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00033  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00034  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00035  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00036  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00037  *
00038  */
00039 
00040 #include <gecode/int/gcc.hh>
00041 #include <gecode/int/distinct.hh>
00042 
00043 namespace Gecode { namespace Int { namespace GCC {
00044 
00055   template<class Card, bool isView>
00056   inline bool
00057   check_alldiff(int n, ViewArray<Card>& k){
00058     if (isView) {
00059       if (k.size() == n) {
00060         for (int i=k.size(); i--;)
00061           if (k[i].min() != 1 || k[i].max() != 1)
00062             return false;
00063         return true;
00064       }
00065       return false;
00066     } else {
00067       for (int i=k.size(); i--;)
00068         if (k[i].min() != 0 || k[i].max() != 1)
00069           return false;
00070       return true;
00071     }
00072   }
00073 
00078   template <class View>
00079   forceinline unsigned int
00080   x_card(Space& home, ViewArray<View>& x) {
00081     int n = x.size();
00082     Region r(home);
00083     ViewRanges<View>* xrange = r.alloc<ViewRanges<View> >(n);
00084     for (int i = n; i--; ){
00085       ViewRanges<View> iter(x[i]);
00086       xrange[i] = iter;
00087     }
00088 
00089     Iter::Ranges::NaryUnion<ViewRanges<View> > drl(&xrange[0], x.size());
00090     return Iter::Ranges::size(drl);
00091   }
00092 
00093 
00101   template<class Card, bool isView>
00102   inline ExecStatus
00103   card_cons(Space& home, ViewArray<Card>& k, int n) {
00104     // this should be the required min and allowed max
00105     int smin = 0;
00106     int smax = 0;
00107     int m    = k.size();
00108     for (int i = m; i--; ) {
00109       int ci = k[i].counter();
00110       if (ci > k[i].max() ) {
00111         // more occurrences of k[i].card() than allowed
00112         return ES_FAILED;
00113       } else {
00114         smax += (k[i].max() - ci);
00115         if (ci < k[i].min()) {
00116           smin += (k[i].min() - ci);
00117         }
00118       }
00119       if (k[i].min() > n) {
00120         // cannot satisfy requiremnts for k[i].card()
00121         return ES_FAILED;
00122       }
00123       if (!k[i].assigned()) {
00124         ModEvent me = k[i].lq(home, n);
00125         if (me_failed(me)) {
00126           return ES_FAILED;
00127         }
00128       }
00129     }
00130 
00131     if (n < smin) {
00132       // not enough variables to satisfy min req
00133       return ES_FAILED;
00134     }
00135 
00136     // since we always reduce the variables to the allowed values we always use all values
00137     if (smax < n) {
00138       // maximal occurrence for the cardinalities cannot be satisfied
00139       return ES_FAILED;
00140     }
00141     return ES_OK;
00142   }
00143 
00149   template<class Card, bool isView>
00150   inline void
00151   post_template(Space& home, ViewArray<IntView>& x, ViewArray<Card>& k,
00152                 IntConLevel& icl){
00153     int n = static_cast<int>(x_card(home, x));
00154     bool rewrite  = false;
00155     rewrite = check_alldiff<Card,isView>(n, k);
00156     GECODE_ES_FAIL(home, (card_cons<Card, isView>(home, k, x.size())));
00157     if (rewrite) {
00158       if (x.same(home))
00159         throw ArgumentSame("Int::distinct");
00160       if (home.failed()) return;
00161       switch (icl) {
00162       case ICL_BND:
00163         GECODE_ES_FAIL(home,Distinct::Bnd<IntView>::post(home,x));
00164         break;
00165       case ICL_DOM:
00166         GECODE_ES_FAIL(home,Distinct::Dom<IntView>::post(home,x));
00167         break;
00168       default:
00169         GECODE_ES_FAIL(home,Distinct::Val<IntView>::post(home,x));
00170       }
00171     } else {
00172       switch (icl) {
00173       case ICL_BND: {
00174         GECODE_ES_FAIL(home, (GCC::Bnd<IntView, Card, isView>::post(home, x, k)));
00175         break;
00176       }
00177       case ICL_DOM: {
00178         GECODE_ES_FAIL(home, (GCC::Dom<IntView, Card, isView>::post(home, x, k)));
00179         break;
00180       }
00181       default: {
00182         GECODE_ES_FAIL(home, (GCC::Val<IntView, Card, isView>::post(home, x, k)));
00183       }
00184       }
00185     }
00186   }
00187 
00188 }}
00189 
00190   using namespace Int;
00191   using namespace Int::GCC;
00192   using namespace Support;
00193 
00194   // variable cardinality
00195 
00196   void count(Space& home, const  IntVarArgs& x,
00197              const  IntVarArgs& c, const  IntArgs& v,
00198              IntConLevel icl) {
00199 
00200     // c = |cards| \forall i\in \{0, \dots, c - 1\}:  cards[i] = \#\{j\in\{0, \dots, |x| - 1\}  | vars_j = values_i\}
00201 
00202     // |cards| = |values|
00203     int vsize = v.size();
00204     int csize = c.size();
00205     if (vsize != csize)
00206       throw ArgumentSizeMismatch("Int::count");
00207     if (x.same(home))
00208       throw ArgumentSame("Int::count");
00209 
00210     if (home.failed())
00211       return;
00212 
00213     ViewArray<IntView> xv(home, x);
00214 
00215     // valid values for the variables in vars
00216     IntSet valid(&v[0], vsize);
00217 
00218     // \forall v \not\in values:  \#(v) = 0
00219     // remove all values from the domains of the variables in vars that are not mentionned in the array \a values
00220     for (int i = xv.size(); i--; ) {
00221       IntSetRanges ir(valid);
00222       GECODE_ME_FAIL(home, xv[i].inter_r(home, ir));
00223     }
00224 
00225     linear(home, c, IRT_EQ, xv.size());
00226 
00227     ViewArray<CardView> cv(home, c);
00228 
00229     // set the cardinality
00230     for (int i = vsize; i--; ) {
00231       cv[i].card(v[i]);
00232       cv[i].counter(0);
00233     }
00234     GCC::post_template<CardView, true>(home, xv, cv, icl);
00235   }
00236 
00237   // domain is 0..|cards|- 1
00238   void count(Space& home, const IntVarArgs& x, const IntVarArgs& c,
00239              IntConLevel icl) {
00240     IntArgs values(c.size());
00241     for (int i = c.size(); i--; )
00242       values[i] = i;
00243     count(home, x, c, values, icl);
00244   }
00245 
00246   // constant cards
00247   void count(Space& home, const IntVarArgs& x,
00248              const IntSetArgs& c, const IntArgs& v,
00249              IntConLevel icl) {
00250     int vsize = v.size();
00251     int csize = c.size();
00252     if (vsize != csize)
00253       throw ArgumentSizeMismatch("Int::count");
00254     if (x.same(home))
00255       throw ArgumentSame("Int::count");
00256     for (int i=c.size(); i--; ) {
00257       Limits::check(v[i],"Int::count");
00258       Limits::check(c[i].min(),"Int::count");
00259       Limits::check(c[i].max(),"Int::count");
00260     }
00261 
00262     if (home.failed())
00263       return;
00264 
00265     // c = |cards| \forall i\in \{0, \dots, c - 1\}:  cards[i] = \#\{j\in\{0, \dots, |x| - 1\}  | vars_j = values_i\}
00266 
00267     // |cards| = |values|
00268     ViewArray<IntView> xv(home, x);
00269 
00270     // valid values for the variables in vars
00271     IntSet valid(&v[0], vsize);
00272 
00273     // \forall v \not\in values:  \#(v) = 0
00274     // remove all values from the domains of the variables in vars that are not mentionned in the array \a values
00275     for (int i = xv.size(); i--; ) {
00276       IntSetRanges ir(valid);
00277       GECODE_ME_FAIL(home, xv[i].inter_r(home, ir));
00278     }
00279 
00280     bool hole_found = false;
00281     for (int i = vsize; i--; )
00282       if (c[i].ranges() > 1) {
00283         hole_found = true; break;
00284       }
00285 
00286     if (hole_found) {
00287       // create temporary variables
00288       ViewArray<CardView> cv(home, vsize);
00289       IntVarArgs cvargs(vsize);
00290       for (int i = vsize; i--; ) {
00291         IntVar card(home, c[i]);
00292         cvargs[i] = card;
00293         IntView viewc(card);
00294         cv[i] = viewc;
00295       }
00296 
00297       // set the cardinality
00298       for (int i = vsize; i--; ) {
00299         cv[i].card(v[i]);
00300         cv[i].counter(0);
00301       }
00302 
00303       linear(home, cvargs, IRT_EQ, xv.size());
00304 
00305       GCC::post_template<CardView, true>(home, xv, cv, icl);
00306     } else {
00307       // all specified cardinalites are ranges
00308 
00309       ViewArray<OccurBndsView> cv(home, csize);
00310       // compute number of zero entries
00311       int z = 0;
00312 
00313       for (int i = csize; i--; ) {
00314         cv[i].card(v[i]);
00315         cv[i].counter(0);
00316         cv[i].min(c[i].min());
00317         cv[i].max(c[i].max());
00318         if (cv[i].max() == 0){
00319           z++;
00320         }
00321       }
00322 
00323       // if there are zero entries
00324       if (z > 0) {
00325         // reduce the occurences
00326         IntArgs rem(z);
00327         z = 0;
00328         for (int j = cv.size(); j--;) {
00329           if (cv[j].max() == 0){
00330             rem[z++] = cv[j].card();
00331           }
00332         }
00333 
00334         IntSet remzero(&rem[0], z);
00335         for (int i = xv.size(); i--; ) {
00336           IntSetRanges remzeror(remzero);
00337           GECODE_ME_FAIL(home, xv[i].minus_r(home, remzeror, false));
00338         }
00339 
00340         GCC::post_template<OccurBndsView,false>(home, xv, cv, icl);
00341       } else {
00342         GCC::post_template<OccurBndsView,false>(home, xv, cv, icl);
00343       }
00344     }
00345   }
00346 
00347   // domain is 0..|cards|- 1
00348   void count(Space& home, const IntVarArgs& x, const IntSetArgs& c,
00349              IntConLevel icl) {
00350     IntArgs values(c.size());
00351     for (int i = c.size(); i--; )
00352       values[i] = i;
00353     count(home, x, c, values, icl);
00354   }
00355 
00356   void count(Space& home, const IntVarArgs& x,
00357              const IntSet& c, const IntArgs& v,
00358              IntConLevel icl) {
00359     IntSetArgs cards(v.size());
00360     for (int i = v.size(); i--; )
00361       cards[i] = c;
00362     count(home, x, cards, v, icl);
00363   }
00364 
00365 }
00366 
00367 // STATISTICS: int-post