Generated on Mon Aug 25 11:35:33 2008 for Gecode by doxygen 1.5.6

atmost.cc

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  *
00006  *  Copyright:
00007  *     Patrick Pekczynski, 2006
00008  *
00009  *  Last modified:
00010  *     $Date: 2008-02-01 14:48:35 +0100 (Fri, 01 Feb 2008) $ by $Author: tack $
00011  *     $Revision: 6039 $
00012  *
00013  *  This file is part of Gecode, the generic constraint
00014  *  development environment:
00015  *     http://www.gecode.org
00016  *
00017  *  Permission is hereby granted, free of charge, to any person obtaining
00018  *  a copy of this software and associated documentation files (the
00019  *  "Software"), to deal in the Software without restriction, including
00020  *  without limitation the rights to use, copy, modify, merge, publish,
00021  *  distribute, sublicense, and/or sell copies of the Software, and to
00022  *  permit persons to whom the Software is furnished to do so, subject to
00023  *  the following conditions:
00024  *
00025  *  The above copyright notice and this permission notice shall be
00026  *  included in all copies or substantial portions of the Software.
00027  *
00028  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00029  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00030  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00031  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00032  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00033  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00034  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00035  *
00036  */
00037 
00038 #include "gecode/cpltset/propagators.hh"
00039 
00040 using namespace Gecode::CpltSet;
00041 
00042 namespace Gecode {
00043   
00044   namespace CpltSet { namespace AtMost {
00045     
00052     template <class View>
00053     void 
00054     atmostOne_post(Space* home, ViewArray<View>& x, int c) {
00055       if (home->failed()) return;
00056       int n = x.size();
00057 
00058       int minx = x[0].initialLubMin();
00059       int maxx = x[0].initialLubMax(); 
00060       unsigned int xtab = x[0].tableWidth();  
00061       for (int i = n; i--;) {
00062         if (x[i].initialLubMin() < minx) {
00063           minx = x[i].initialLubMin();
00064         }
00065         if (x[i].initialLubMax() > maxx) {
00066           maxx = x[i].initialLubMax();
00067         }
00068         if (x[i].tableWidth() > xtab) {
00069           xtab = x[i].tableWidth();
00070         }
00071       }
00072 
00073       bdd d0 = bdd_true();     
00074       for (int i = 0; i < n; i++) {
00075         unsigned int xoff = x[i].offset();
00076         unsigned int xtab = x[i].tableWidth();
00077         d0 &= cardcheck(xtab, xoff, c, c);    
00078       }
00079 
00080       for (int i = 0; i < n - 1; i++) {
00081         for (int j = i + 1; j < n; j++) {
00082           d0 &= extcardcheck(x[i], x[j], 0, 1);
00083         }
00084       }
00085       GECODE_ES_FAIL(home, NaryCpltSetPropagator<View>::post(home, x, d0));
00086     }
00087 
00088     template <class View>
00089     void 
00090     atmost_post(Space* home, ViewArray<View>& x, int c, 
00091                 SetRelType, int) {
00092       if (home->failed()) return;
00093 
00094       unsigned int x1_tab = x[1].tableWidth();
00095 
00096       // cardinality description for the intersection x \cap y
00097       bdd d0 = bdd_true();
00098 
00099       // equivalence of intersection x \cap y with intermediate variable z
00100       for (unsigned int i = x1_tab; i--;) {
00101         d0 &= ((x[0].element(i) & x[1].element(i)) % (x[2].element(i)));
00102       }
00103 
00104       // cardinality description of intermediate variable z
00105       bdd c0 = bdd_true();
00106       unsigned int off = x[2].offset();
00107       unsigned int tab = x[2].tableWidth();
00108 
00109       c0 = cardcheck(tab, off, 0, c);
00110 
00111       // combination of intersection and cardinality
00112       d0 &= c0;
00113 
00114       GECODE_ES_FAIL(home, NaryCpltSetPropagator<View>::post(home, x, d0));
00115 
00116     }
00117 
00118     template <class View>
00119     void 
00120     atmost_post(Space* home, ViewArray<View>& x, int c, 
00121                 CpltSetRelType lex, int card) {
00122       if (home->failed()) return;
00123 
00124       unsigned int x1_tab = x[1].tableWidth();
00125 
00126       // cardinality description for the intersection x \cap y
00127       bdd d0 = bdd_true();
00128 
00129       // equivalence of intersection x \cap y with intermediate variable z
00130       for (unsigned int i = x1_tab; i--;) {
00131         d0 &= ((x[0].element(i) & x[1].element(i)) % (x[2].element(i)));
00132       }
00133 
00134       // cardinality description of intermediate variable z
00135       bdd c0 = bdd_true();
00136       unsigned int off = x[2].offset();
00137       unsigned int tab = x[2].tableWidth();
00138 
00139       c0 = cardcheck(tab, off, 0, c);
00140 
00141       // combination of intersection and cardinality
00142       d0 &= c0;
00143 
00144       // lexicographic constraint x[0] < x[1]
00145 
00146       unsigned int xoff = x[0].offset();
00147       unsigned int yoff = x[1].offset();
00148       unsigned int xtab = x[0].tableWidth();
00149       unsigned int ytab = x[1].tableWidth();
00150       switch (lex) {
00151       case SRT_LE:
00152         {
00153           d0 &= lexlt(xoff, yoff, xtab, xtab - 1);
00154           break;
00155         }
00156       case SRT_GR:
00157         {
00158           d0 &= lexlt(yoff, xoff, xtab, xtab - 1);
00159           break;
00160         }
00161       case SRT_LQ:
00162         {
00163           d0 &= lexlq(xoff, yoff, xtab, xtab - 1);
00164           break;
00165         }
00166       case SRT_GQ:
00167         {
00168           d0 &= lexlq(yoff, xoff, xtab, xtab - 1);
00169           break;
00170         }
00171       case SRT_LE_REV:
00172         {
00173           d0 &= lexltrev(xoff, yoff, xtab, 0);
00174           break;
00175         }
00176       case SRT_GR_REV:
00177         {
00178           d0 &= lexltrev(yoff, xoff, xtab, 0);
00179           break;
00180         }
00181       case SRT_LQ_REV:
00182         {
00183           d0 &= lexlqrev(xoff, yoff, xtab, 0);
00184           break;
00185         }
00186       case SRT_GQ_REV:
00187         {
00188           d0 &= lexlqrev(yoff, xoff, xtab, 0);
00189           break;
00190         }
00191       default:
00192         {
00193           // dont use additional lexicographic ordering
00194           break;
00195         }
00196       }
00197 
00198 
00199       GECODE_ES_FAIL(home, NaryCpltSetPropagator<View>::post(home, x, d0));
00200 
00201     }
00202 
00203     template <class View>
00204     void 
00205     atmost_post(Space* home, View& x, View& y, int c, CpltSetRelType lex,
00206                 int card) {
00207       if (home->failed()) return;
00208 
00209       unsigned int xoff = x.offset();
00210       unsigned int yoff = y.offset();
00211       unsigned int xtab = x.tableWidth();
00212       unsigned int ytab = y.tableWidth();
00213 
00214       // cardinality description for the intersection x \cap y
00215       bdd d0 = bdd_true();
00216       d0 = extcardcheck(x, y, 0, c);
00217 
00218       // extra lexicographic order on bit strings x \sim_{lex} y
00219       switch (lex) {
00220       case SRT_LE:
00221         {
00222           d0 &= lexlt(xoff, yoff, xtab, xtab - 1);
00223           break;
00224         }
00225       case SRT_GR:
00226         {
00227           d0 &= lexlt(yoff, xoff, xtab, xtab - 1);
00228           break;
00229         }
00230       case SRT_LQ:
00231         {
00232           d0 &= lexlq(xoff, yoff, xtab, xtab - 1);
00233           break;
00234         }
00235       case SRT_GQ:
00236         {
00237           d0 &= lexlq(yoff, xoff, xtab, xtab - 1);
00238           break;
00239         }
00240       case SRT_LE_REV:
00241         {
00242           d0 &= lexltrev(xoff, yoff, xtab, 0);
00243           break;
00244         }
00245       case SRT_GR_REV:
00246         {
00247           d0 &= lexltrev(yoff, xoff, xtab, 0);
00248           break;
00249         }
00250       case SRT_LQ_REV:
00251         {
00252           d0 &= lexlqrev(xoff, yoff, xtab, 0);
00253           break;
00254         }
00255       case SRT_GQ_REV:
00256         {
00257           d0 &= lexlqrev(yoff, xoff, xtab, 0);
00258           break;
00259         }
00260       default:
00261         {
00262           // dont use additional lexicographic ordering
00263           break;
00264         }
00265       }
00266 
00267       // extra cardinality information on x and y
00268       if (card > -1) {
00269         d0 &= cardcheck(xtab, xoff, card, card);
00270         d0 &= cardcheck(ytab, yoff, card, card);
00271       }
00272 
00273       if (x.assigned()) {
00274         d0 &= x.dom();
00275       }
00276 
00277       if (y.assigned()) {
00278         d0 &= y.dom();
00279       }
00280       GECODE_ES_FAIL(home,
00281         (BinaryCpltSetPropagator<View,View>::post(home, x, y, d0)));
00282     }
00283 
00284     template <class View>
00285     void 
00286     atmost_post(Space* home, View& x, View& y, int c, SetRelType,
00287                 int card) {
00288       if (home->failed()) return;
00289 
00290       unsigned int xoff = x.offset();
00291       unsigned int yoff = y.offset();
00292       unsigned int xtab = x.tableWidth();
00293       unsigned int ytab = y.tableWidth();
00294 
00295       // cardinality description for the intersection x \cap y
00296       bdd d0 = bdd_true();
00297       d0 = extcardcheck(x, y, 0, c);
00298 
00299       // dont use additional lexicographic ordering
00300 
00301       // extra cardinality information on x and y
00302       if (card > -1) {
00303         d0 &= cardcheck(xtab, xoff, card, card);
00304         d0 &= cardcheck(ytab, yoff, card, card);
00305       }
00306 
00307       if (x.assigned()) {
00308         d0 &= x.dom();
00309       }
00310 
00311       if (y.assigned()) {
00312         d0 &= y.dom();
00313       }
00314       GECODE_ES_FAIL(home,
00315         (BinaryCpltSetPropagator<View,View>::post(home, x, y, d0)));
00316     }
00317 
00318     template <class Rel>
00319     forceinline void 
00320     atmost_con(Space* home, const CpltSetVar& x, const CpltSetVar& y, int c, 
00321                Rel lex, int card) {
00322       CpltSetView xv(x);
00323       CpltSetView yv(y);
00324       atmost_post(home, xv, yv, c, lex, card);
00325     }
00326 
00327     template <class Rel>
00328     forceinline void 
00329     atmost_con(Space* home, const CpltSetVar& x, const CpltSetVar& y,
00330                const CpltSetVar& z, int c, Rel lex, int card) {
00331       ViewArray<CpltSetView> bv(home, 3);
00332       bv[0] = x;
00333       bv[1] = y;
00334       bv[2] = z;
00335       atmost_post(home, bv, c, lex, card);
00336     }
00337 
00338 
00339     forceinline void 
00340     atmostOne_con(Space* home, const CpltSetVarArgs& x, int c) {
00341       int n = x.size();
00342       ViewArray<CpltSetView> bv(home, n);
00343       for (int i = 0; i < n; i++) {
00344         bv[i] = x[i];
00345       }
00346       atmostOne_post(home, bv, c);
00347     }
00348   
00349     
00350   }} // end namespace CpltSet::AtMost
00351 
00352   using namespace CpltSet::AtMost;
00353 
00354   void
00355   exactly(Space* home, CpltSetVar x, IntSet& is, unsigned int c) {
00356     if (home->failed()) return;
00357     Set::Limits::check(c, "CpltSet::exactly");
00358 
00359     ViewArray<CpltSetView> bv(home, 1);
00360     bv[0] = x;
00361     // Subsumption check
00362     CpltSetVarGlbRanges glb(x);
00363     if (glb()) {
00364       IntSetRanges ir(is);
00365       Gecode::Iter::Ranges::Inter<CpltSetVarGlbRanges, IntSetRanges> 
00366         inter(glb, ir);
00367       if (inter()) {
00368         int s = inter.width();
00369         ++inter;
00370         if (!inter() && s == 1) {
00371           return;
00372         } else {
00373           home->fail();
00374           return;
00375         }
00376       }
00377     }
00378 
00379     CpltSetVarUnknownRanges delta(x);
00380     IntSetRanges irange(is);
00381     Gecode::Iter::Ranges::Inter<CpltSetVarUnknownRanges, IntSetRanges> 
00382       interdel(delta, irange);
00383     if (!interdel()) {
00384       home->fail();
00385       return;
00386     } 
00387 
00388     int mi = interdel.min();
00389     int ma = interdel.max();
00390     int s = interdel.width();
00391     ++interdel;
00392     if (!interdel() && s == 1) {
00393       GECODE_ME_FAIL(home, bv[0].include(home, mi));
00394       return;
00395     }
00396 
00397     Iter::Ranges::SingletonAppend<
00398       Gecode::Iter::Ranges::Inter<CpltSetVarUnknownRanges, IntSetRanges>
00399       > si(mi,ma,interdel);
00400 
00401     unsigned int xtab = bv[0].tableWidth();
00402     unsigned int xoff = bv[0].offset();
00403     int xmin = bv[0].initialLubMin();
00404     
00405     bdd d = cardConst(xtab, xoff, xmin, c, c, si);
00406     GECODE_ES_FAIL(home,
00407       UnaryCpltSetPropagator<CpltSetView>::post(home, bv[0], d));
00408   }
00409 
00410   void
00411   atmost(Space* home, CpltSetVar x, IntSet& is, unsigned int c) {
00412     Set::Limits::check(c, "CpltSet::atmost");
00413     if (home->failed()) return;
00414     ViewArray<CpltSetView> bv(home, 1);
00415     bv[0] = x;
00416 
00417     unsigned int xtab = bv[0].tableWidth();
00418     unsigned int xoff = bv[0].offset();
00419     int xmin = bv[0].initialLubMin();
00420     IntSetRanges ir(is);
00421     bdd d = cardConst(xtab, xoff, xmin, 0, c, ir);
00422 
00423     GECODE_ES_FAIL(home,
00424       UnaryCpltSetPropagator<CpltSetView>::post(home, bv[0], d));
00425   }
00426 
00427   void 
00428   atmost(Space* home, CpltSetVar x, CpltSetVar y, unsigned int c) {
00429     Set::Limits::check(c, "CpltSet::atmost");
00430     atmost_con(home, x, y, c, SRT_EQ, -1);
00431   }
00432 
00433   void 
00434   atmostLex(Space* home, CpltSetVar x, CpltSetVar y, unsigned int c, 
00435             CpltSetRelType lex) {
00436     Set::Limits::check(c, "CpltSet::atmostLex");
00437     atmost_con(home, x, y, c, lex, -1);
00438   }
00439 
00440   void 
00441   atmostLexCard(Space* home, CpltSetVar x, CpltSetVar y, unsigned int c, 
00442                 CpltSetRelType lex, unsigned int d) {
00443     Set::Limits::check(c, "CpltSet::atmostLexCard");
00444     Set::Limits::check(d, "CpltSet::atmostLexCard");
00445     atmost_con(home, x, y, c, lex, d);
00446   }
00447 
00448   void 
00449   atmostCard(Space* home, CpltSetVar x, CpltSetVar y, unsigned int c,
00450              unsigned int d) {
00451     Set::Limits::check(c, "CpltSet::atmostCard");
00452     Set::Limits::check(d, "CpltSet::atmostCard");
00453     atmost_con(home, x, y, c, SRT_EQ, d);
00454   }
00455 
00456   void 
00457   atmost(Space* home, CpltSetVar x, CpltSetVar y, CpltSetVar z,
00458          unsigned int c) {
00459     Set::Limits::check(c, "CpltSet::atmost");
00460     atmost_con(home, x, y, z, c, SRT_EQ, -1);
00461   }
00462 
00463   void 
00464   atmostOne(Space* home, const CpltSetVarArgs& x, unsigned int c) {
00465     Set::Limits::check(c, "CpltSet::atmostOne");
00466     atmostOne_con(home, x, c);
00467   }
00468 
00469 
00470 }
00471 
00472 // STATISTICS: cpltset-post