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

inter.icc

Go to the documentation of this file.
00001 /*
00002  *  Main authors:
00003  *     Guido Tack <tack@gecode.org>
00004  *     Christian Schulte <schulte@gecode.org>
00005  *
00006  *  Contributing authors:
00007  *     Gabor Szokoli <szokoli@gecode.org>
00008  *
00009  *  Copyright:
00010  *     Guido Tack, 2004
00011  *     Christian Schulte, 2004
00012  *     Gabor Szokoli, 2004
00013  *
00014  *  Last modified:
00015  *     $Date: 2005-11-17 23:57:02 +0100 (Thu, 17 Nov 2005) $ by $Author: tack $
00016  *     $Revision: 2601 $
00017  *
00018  *  This file is part of Gecode, the generic constraint
00019  *  development environment:
00020  *     http://www.gecode.org
00021  *
00022  *  See the file "LICENSE" for information on usage and
00023  *  redistribution of this file, and for a
00024  *     DISCLAIMER OF ALL WARRANTIES.
00025  *
00026  */
00027 
00028 namespace Gecode { namespace Set { namespace RelOp {
00029 
00030   /*
00031    * "Ternary intersection" propagator
00032    *
00033    */
00034 
00035   template <class View0, class View1, class View2> ExecStatus
00036   Intersection<View0,View1,View2>::post(Space* home,
00037                                         View0 x0,View1 x1,View2 x2) {
00038     (void) new (home) Intersection<View0,View1,View2>(home,x0,x1,x2);
00039     return ES_OK;
00040   }
00041 
00042   template <class View0, class View1, class View2>
00043   Actor*
00044   Intersection<View0,View1,View2>::copy(Space* home, bool share) {
00045     return new (home) Intersection(home,share,*this);
00046   }
00047 
00048 
00049   template <class View0, class View1, class View2>
00050   ExecStatus
00051   Intersection<View0,View1,View2>::propagate(Space* home) {
00052 
00053     bool x0ass=x0.assigned();
00054     bool x1ass=x1.assigned();
00055     bool x2ass=x2.assigned();
00056 
00057     {
00058       GlbRanges<View2> x2lb(x2);
00059       GECODE_ME_CHECK( x0.includeI(home,x2lb) );
00060     }
00061     {
00062       GlbRanges<View2> x2lb(x2);
00063       GECODE_ME_CHECK( x1.includeI(home,x2lb) );
00064     }
00065     {
00066       GlbRanges<View0> x0lb(x0);
00067       LubRanges<View2> x2ub(x2);
00068       Iter::Ranges::Diff<GlbRanges<View0>,LubRanges<View2> > m1(x0lb,x2ub);
00069       GECODE_ME_CHECK( x1.excludeI(home,m1) );
00070     }
00071     {
00072       GlbRanges<View1> x1lb(x1);
00073       LubRanges<View2> x2ub(x2);
00074 
00075       Iter::Ranges::Diff<GlbRanges<View1>,LubRanges<View2> > m2(x1lb,x2ub);
00076       GECODE_ME_CHECK( x0.excludeI(home,m2) );
00077     }
00078     {
00079       GlbRanges<View0> x0lb(x0);
00080       GlbRanges<View1> x1lb(x1);
00081       Iter::Ranges::Inter<GlbRanges<View0>,GlbRanges<View1> > i1(x0lb,x1lb);
00082       GECODE_ME_CHECK( x2.includeI(home,i1) );
00083     }
00084     {
00085       LubRanges<View0> x0ub(x0);
00086       LubRanges<View1> x1ub(x1);
00087       Iter::Ranges::Inter<LubRanges<View0>,LubRanges<View1> > i2(x0ub,x1ub);
00088       GECODE_ME_CHECK( x2.intersectI(home,i2) );
00089     }
00090     unsigned int m, n;
00091     {
00092       LubRanges<View0> x0ub(x0);
00093       LubRanges<View1> x1ub(x1);
00094       Iter::Ranges::Union<LubRanges<View0>,LubRanges<View1> > u1(x0ub,x1ub);
00095       m = Iter::Ranges::size(u1);
00096       n = x0.cardMin()+x1.cardMin();
00097       if (n>m)
00098         GECODE_ME_CHECK( x2.cardMin(home,n-m) );
00099     }
00100     unsigned int s2;
00101     {
00102       LubRanges<View0> x0ub(x0);
00103       GlbRanges<View1> x1lb(x1);
00104       Iter::Ranges::Diff<GlbRanges<View1>,LubRanges<View0> > d2(x1lb,x0ub);
00105       s2 = Iter::Ranges::size(d2);
00106       assert (s2 <= x1.cardMax());
00107       GECODE_ME_CHECK( x2.cardMax(home,x1.cardMax()-s2) );
00108     }
00109     {
00110       LubRanges<View1> x1ub(x1);
00111       GlbRanges<View0> x0lb(x0);
00112       Iter::Ranges::Diff<GlbRanges<View0>,LubRanges<View1> > d1 (x0lb,x1ub);
00113       unsigned int s1 = Iter::Ranges::size(d1);
00114       assert (s1 <= x0.cardMax());
00115       GECODE_ME_CHECK( x2.cardMax(home,x0.cardMax()-s1) );
00116       if (m+x2.cardMax() > x1.cardMin())
00117         GECODE_ME_CHECK( x0.cardMax(home,m+x2.cardMax()-x1.cardMin()) );
00118       //I might have to recaluclate m here?
00119       if (m+x2.cardMax() > x0.cardMin())
00120         GECODE_ME_CHECK( x1.cardMax(home,m+x2.cardMax()-x0.cardMin()) );
00121       //s1 and s2 could be outdated too...
00122       GECODE_ME_CHECK( x0.cardMin(home,s1+x2.cardMin()) );
00123       GECODE_ME_CHECK( x1.cardMin(home,s2+x2.cardMin()) );
00124     }
00125     if ( x0ass + x1ass + x2ass >= 2 ) return ES_SUBSUMED;
00126 
00127     return ES_NOFIX;
00128   }
00129 
00130   template <class View0, class View1, class View2>
00131   forceinline
00132   Intersection<View0,View1,View2>::Intersection(Space* home,
00133                                              View0 y0,View1 y1,View2 y2)
00134     : InhomTernaryPropagator<View0,PC_SET_ANY,View1,PC_SET_ANY,
00135                              View2,PC_SET_ANY>(home,y0,y1,y2) {}
00136 
00137   template <class View0, class View1, class View2>
00138   forceinline
00139   Intersection<View0,View1,View2>::Intersection(Space* home, bool share,
00140                                              Intersection<View0,View1,View2>& p)
00141     : InhomTernaryPropagator<View0,PC_SET_ANY,View1,PC_SET_ANY,
00142                              View2,PC_SET_ANY>(home,share,p) {}
00143 
00144   /*
00145    * "Nary intersection" propagator
00146    *
00147    */
00148 
00149   template <class View0, class View1>
00150   forceinline
00151   IntersectionN<View0,View1>::IntersectionN(Space* home, ViewArray<View0>& x,
00152                                             View1 y)
00153     : InhomNaryOnePropagator<View0,PC_SET_ANY,View1,PC_SET_ANY>(home,x,y),
00154       intOfDets(home) {
00155     shared = x.shared() || viewarrayshared(x,y);
00156   }
00157 
00158   template <class View0, class View1>
00159   forceinline
00160   IntersectionN<View0,View1>::IntersectionN(Space* home, bool share,
00161                                             IntersectionN& p)
00162     : InhomNaryOnePropagator<View0,PC_SET_ANY,View1,PC_SET_ANY>(home,share,p),
00163       shared(p.shared),
00164       intOfDets() {
00165     intOfDets.update(home, p.intOfDets);
00166   }
00167 
00168   template <class View0, class View1>
00169   ExecStatus
00170   IntersectionN<View0,View1>::post(Space* home,
00171                                    ViewArray<View0>& x, View1 y) {
00172     switch (x.size()) {
00173     case 0:
00174       GECODE_ME_CHECK(y.cardMin(home, Limits::Set::card_max));
00175       return ES_OK;
00176     case 1:
00177       return Rel::Eq<View0,View1>::post(home, x[0], y);
00178     case 2:
00179       return Intersection<View0,View0,View1>::post(home, x[0], x[1], y);
00180     default:
00181       (void) new (home) IntersectionN<View0,View1>(home,x,y);
00182       return ES_OK;
00183     }
00184   }
00185 
00186   template <class View0, class View1>
00187   Actor*
00188   IntersectionN<View0,View1>::copy(Space* home, bool share) {
00189     return new (home) IntersectionN<View0,View1>(home,share,*this);
00190   }
00191 
00192   template <class View0, class View1>
00193   PropCost
00194   IntersectionN<View0,View1>::cost(void) const {
00195     return PC_QUADRATIC_LO;
00196   }
00197 
00198   template <class View0, class View1>
00199   ExecStatus
00200   IntersectionN<View0,View1>::propagate(Space* home) {
00201 
00202     bool repeat = false;
00203     do {
00204       repeat = false;
00205       int xsize = x.size();
00206 
00207       for (int i = xsize; i--; ) {
00208         GECODE_ME_CHECK( y.cardMax(home,x[i].cardMax()) );
00209         GECODE_ME_CHECK( x[i].cardMin(home,y.cardMin()) );
00210         if (x[i].cardMax()==0) {
00211           GECODE_ME_CHECK( y.exclude(home,
00212                                      Limits::Set::int_min,
00213                                      Limits::Set::int_max) );
00214           intOfDets.dispose(home);
00215           return ES_SUBSUMED;
00216         }
00217       }
00218       {
00219         GECODE_AUTOARRAY(GlbRanges<View0>,xLBs,xsize);
00220         GECODE_AUTOARRAY(LubRanges<View0>,xUBs,xsize);
00221         for (int i = xsize; i--; ) {
00222           GlbRanges<View0> lb(x[i]);
00223           LubRanges<View0> ub(x[i]);
00224           xLBs[i]=lb;
00225           xUBs[i]=ub;
00226         }
00227         Iter::Ranges::NaryInter<GlbRanges<View0> > lbi(xLBs,xsize);
00228         BndSetRanges dets1(intOfDets);
00229         Iter::Ranges::Inter< Iter::Ranges::NaryInter<GlbRanges<View0> >,
00230           BndSetRanges >
00231           lbiAll(lbi,dets1);
00232         GECODE_ME_CHECK( y.includeI(home,lbiAll) );
00233 
00234         Iter::Ranges::NaryInter<LubRanges<View0> > ubi(xUBs,xsize);
00235         BndSetRanges dets2(intOfDets);
00236         Iter::Ranges::Inter< Iter::Ranges::NaryInter<LubRanges<View0> >,
00237           BndSetRanges >
00238           ubiAll(ubi,dets2);
00239         GECODE_ME_CHECK( y.intersectI(home,ubiAll) );
00240       }
00241 
00242       for (int i = xsize; i--; ) {
00243         GlbRanges<View1> ylb(y);
00244         GECODE_ME_CHECK( x[i].includeI(home,ylb) );
00245       }
00246 
00247       // xi.exclude (Intersection(xj.lb) - y.ub)
00248       {
00249         GECODE_AUTOARRAY(GLBndSet, rightSet, xsize);
00250         rightSet[xsize-1].init(home);
00251         rightSet[xsize-1].update(home,intOfDets);
00252         for (int i=xsize-1;i--;) {
00253           GlbRanges<View0> xilb(x[i+1]);
00254           BndSetRanges prev(rightSet[i+1]);
00255           Iter::Ranges::Inter<GlbRanges<View0>,
00256             BndSetRanges> inter(xilb,prev);
00257           rightSet[i].init(home);
00258           rightSet[i].includeI(home,inter);
00259         }
00260 
00261         LUBndSet leftAcc(home);
00262 
00263         for (int i=0;i<xsize;i++) {
00264           BndSetRanges left(leftAcc);
00265           BndSetRanges right(rightSet[i]);
00266           Iter::Ranges::Inter<BndSetRanges,
00267             BndSetRanges> inter(left, right);
00268           LubRanges<View1> yub(y);
00269           Iter::Ranges::Diff<Iter::Ranges::Inter<BndSetRanges,
00270             BndSetRanges>, LubRanges<View1> >
00271             forbidden(inter, yub);
00272           GECODE_ME_CHECK( x[i].excludeI(home,forbidden) );
00273           GlbRanges<View0> xlb(x[i]);
00274           leftAcc.intersectI(home,xlb);
00275         }
00276         for (int i=xsize; i--;)
00277           rightSet[i].dispose(home);
00278         leftAcc.dispose(home);
00279       }
00280 
00281 
00282       for(int i=0;i<x.size();i++){
00283         //Do not reverse! Eats away the end of the array!
00284         while (i<x.size() && x[i].assigned()) {
00285           GlbRanges<View0> det(x[i]);
00286           if (intOfDets.intersectI(home,det)) {repeat = true;}
00287           x.move_lst(i);
00288           if (intOfDets.size()==0) {
00289             GECODE_ME_CHECK( y.exclude(home,Limits::Set::int_min,
00290                                        Limits::Set::int_max) );
00291             intOfDets.dispose(home);
00292             return ES_SUBSUMED;
00293           }
00294         }
00295       }
00296       if (x.size()==0) {
00297         BndSetRanges all1(intOfDets);
00298         GECODE_ME_CHECK( y.intersectI(home,all1) );
00299         BndSetRanges all2(intOfDets);
00300         GECODE_ME_CHECK( y.includeI(home,all2) );
00301         intOfDets.dispose(home);
00302         return ES_SUBSUMED;
00303       }
00304 
00305     } while (repeat);
00306 
00307     return shared ? ES_NOFIX : ES_FIX;
00308   }
00309 
00310 }}}
00311 
00312 // STATISTICS: set-prop