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

disjoint.cc

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  *  Copyright:
00007  *     Guido Tack, 2004
00008  *     Christian Schulte, 2004
00009  *
00010  *  Last modified:
00011  *     $Date: 2006-05-29 09:42:21 +0200 (Mon, 29 May 2006) $ by $Author: schulte $
00012  *     $Revision: 3246 $
00013  *
00014  *  This file is part of Gecode, the generic constraint
00015  *  development environment:
00016  *     http://www.gecode.org
00017  *
00018  *  See the file "LICENSE" for information on usage and
00019  *  redistribution of this file, and for a
00020  *     DISCLAIMER OF ALL WARRANTIES.
00021  *
00022  */
00023 
00024 
00025 
00026 #include "gecode/set/select.hh"
00027 #include "gecode/set/rel.hh"
00028 #include "gecode/set/rel-op.hh"
00029 #include "gecode/set.hh"
00030 
00031 #include "gecode/iter.hh"
00032 
00033 namespace Gecode { namespace Set { namespace Select {
00034 
00035   PropCost
00036   SelectDisjoint::cost(void) const {
00037     return PC_QUADRATIC_LO;
00038   }
00039 
00040   size_t
00041   SelectDisjoint::dispose(Space* home) {
00042     assert(!home->failed());
00043     x1.cancel(home,this, PC_SET_ANY);
00044     iv.cancel(home,this,PC_SET_ANY);
00045     (void) Propagator::dispose(home);
00046     return sizeof(*this);
00047   }
00048 
00049   Actor*
00050   SelectDisjoint::copy(Space* home, bool share) {
00051     return new (home) SelectDisjoint(home,share,*this);
00052   }
00053 
00054   ExecStatus
00055   SelectDisjoint::propagate(Space* home) {
00056     int n = iv.size();
00057 
00058     bool fix_flag;
00059     do {
00060       fix_flag=false;
00061 
00062       // Compute union of all selected elements' lower bounds
00063       GlbRanges<SetView> x1lb(x1);
00064       Iter::Ranges::ToValues<GlbRanges<SetView> > vx1lb(x1lb);
00065       GLBndSet unionOfSelected(home);
00066       for(int i=0; vx1lb(); ++vx1lb) {
00067         while (iv[i].idx < vx1lb.val()) i++;
00068         GlbRanges<SetView> clb(iv[i].var);
00069         unionOfSelected.includeI(home,clb);
00070       }
00071 
00072       {
00073         LubRanges<SetView> x1ub(x1);
00074         Iter::Ranges::ToValues<LubRanges<SetView> > vx1ub(x1ub);
00075         int i=0;
00076         int j=0;
00077         // Cancel all elements that are no longer in the upper bound
00078         while (vx1ub()) {
00079           if (iv[i].idx < vx1ub.val()) {
00080             iv[i].var.cancel(home,this, PC_SET_ANY);
00081             i++;
00082             continue;
00083           }
00084           iv[j] = iv[i];
00085           ++vx1ub;
00086           ++i; ++j;
00087         }
00088 
00089         // cancel the variables with index greater than
00090         // max of lub(x1)
00091         for (int k=i; k<n; k++) {
00092           iv[k].var.cancel(home,this, PC_SET_ANY);
00093         }
00094         n = j;
00095         iv.size(n);
00096       }
00097 
00098       {
00099       UnknownRanges<SetView> x1u(x1);
00100       Iter::Ranges::Cache<UnknownRanges<SetView> > x1uc(x1u);
00101       Iter::Ranges::ToValues<Iter::Ranges::Cache<UnknownRanges<SetView> > >
00102         vx1u(x1uc);
00103       int i=0;
00104       int j=0;
00105       while (vx1u()) {
00106         while (iv[i].idx < vx1u.val()) {
00107           iv[j] = iv[i];
00108           i++; j++;
00109         }
00110         assert(iv[i].idx == vx1u.val());
00111 
00112         SetView candidate = iv[i].var;
00113         int candidateInd = iv[i].idx;
00114 
00115         GlbRanges<SetView> clb(candidate);
00116         BndSetRanges uos(unionOfSelected);
00117         Iter::Ranges::Inter<GlbRanges<SetView>, BndSetRanges>
00118           inter(clb, uos);
00119         if (inter()) {
00120           ModEvent me = x1.exclude(home,candidateInd);
00121           fix_flag |= me_modified(me);
00122           GECODE_ME_CHECK(me);
00123 
00124           candidate.cancel(home,this, PC_SET_ANY);
00125           ++i;
00126           ++vx1u;
00127           continue;
00128         }
00129         iv[j] = iv[i];
00130         ++vx1u;
00131         ++i; ++j;
00132       }
00133 
00134       unionOfSelected.dispose(home);
00135 
00136       // copy remaining variables
00137       for (int k=i; k<n; k++) {
00138         iv[j] = iv[k];
00139         j++;
00140       }
00141       n = j;
00142       iv.size(n);
00143       }
00144 
00145       if (x1.cardMax()==0) {
00146         // Selector is empty, we're done
00147         return ES_SUBSUMED;
00148       }
00149 
00150       {
00151         // remove all elements in a selected variable from
00152         // all other selected variables
00153         GlbRanges<SetView> x1lb(x1);
00154         Iter::Ranges::ToValues<GlbRanges<SetView> > vx1lb(x1lb);
00155         int i=0;
00156         for (; vx1lb(); ++vx1lb) {
00157           while (iv[i].idx < vx1lb.val()) i++;
00158           assert(iv[i].idx==vx1lb.val());
00159           GlbRanges<SetView> x1lb2(x1);
00160           Iter::Ranges::ToValues<GlbRanges<SetView> > vx1lb2(x1lb2);
00161           for (int j=0; vx1lb2(); ++vx1lb2) {
00162             while (iv[j].idx < vx1lb2.val()) j++;
00163             assert(iv[j].idx==vx1lb2.val());
00164             if (iv[i].idx!=iv[j].idx) {
00165               GlbRanges<SetView> xilb(iv[i].var);
00166               ModEvent me = iv[j].var.excludeI(home,xilb);
00167               GECODE_ME_CHECK(me);
00168             }
00169           }
00170         }
00171       }
00172 
00173       // remove all elements from the selector that overlap
00174       // with all other possibly selected elements, if
00175       // at least two more elements need to be selected
00176       if (x1.cardMin()-x1.glbSize() > 1) {
00177         UnknownRanges<SetView> x1u(x1);
00178         Iter::Ranges::Cache<UnknownRanges<SetView> > x1uc(x1u);
00179         Iter::Ranges::ToValues<Iter::Ranges::Cache<UnknownRanges<SetView> > >
00180           vx1u(x1uc);
00181 
00182         for (; vx1u() && x1.cardMin()-x1.glbSize() > 1; ++vx1u) {
00183           int i = 0;
00184           while (iv[i].idx < vx1u.val()) i++;
00185           assert(iv[i].idx == vx1u.val());
00186           bool flag=true;
00187 
00188           UnknownRanges<SetView> x1u2(x1);
00189           Iter::Ranges::ToValues<UnknownRanges<SetView> > vx1u2(x1u2);
00190           for (; vx1u2(); ++vx1u2) {
00191             int j = 0;
00192             while (iv[j].idx < vx1u2.val()) j++;
00193             assert(iv[j].idx == vx1u2.val());
00194             if (iv[i].idx!=iv[j].idx) {
00195               GlbRanges<SetView> xjlb(iv[j].var);
00196               GlbRanges<SetView> xilb(iv[i].var);
00197               Iter::Ranges::Inter<GlbRanges<SetView>, GlbRanges<SetView> >
00198                 inter(xjlb, xilb);
00199               if (!inter()) {
00200                 flag = false;
00201                 goto here;
00202               }
00203             }
00204           }
00205         here:
00206           if (flag) {
00207             ModEvent me = x1.exclude(home,iv[i].idx);
00208             GECODE_ME_CHECK(me);
00209           }
00210         }
00211       }
00212 
00213       // if exactly two more elements need to be selected
00214       // and there is a possible element i such that all other pairs of
00215       // elements overlap, select i
00216       UnknownRanges<SetView> x1u(x1);
00217       Iter::Ranges::Cache<UnknownRanges<SetView> > x1uc(x1u);
00218       Iter::Ranges::ToValues<Iter::Ranges::Cache<UnknownRanges<SetView> > >
00219         vx1u(x1uc);
00220 
00221       for (; x1.cardMin()-x1.glbSize() == 2 && vx1u(); ++vx1u) {
00222         int i = 0;
00223         while (iv[i].idx < vx1u.val()) i++;
00224         assert (iv[i].idx == vx1u.val());
00225         bool flag=true;
00226 
00227         UnknownRanges<SetView> x1u2(x1);
00228         Iter::Ranges::ToValues<UnknownRanges<SetView> > vx1u2(x1u2);
00229         for (; vx1u2(); ++vx1u2) {
00230           int j = 0;
00231           while (iv[j].idx < vx1u2.val()) j++;
00232           assert (iv[j].idx == vx1u2.val());
00233           if (iv[i].idx!=iv[j].idx) {
00234             UnknownRanges<SetView> x1u3(x1);
00235             Iter::Ranges::ToValues<UnknownRanges<SetView> > vx1u3(x1u3);
00236             for (; vx1u3(); ++vx1u3) {
00237               int k = 0;
00238               while (iv[k].idx < vx1u3.val()) k++;
00239               assert (iv[k].idx == vx1u3.val());
00240               if (iv[j].idx!=iv[k].idx && iv[i].idx!=iv[k].idx) {
00241                 GlbRanges<SetView> xjlb(iv[j].var);
00242                 GlbRanges<SetView> xilb(iv[k].var);
00243                 Iter::Ranges::Inter<GlbRanges<SetView>, GlbRanges<SetView> >
00244                   inter(xjlb, xilb);
00245                 if (!inter()) {
00246                   flag = false;
00247                   goto here2;
00248                 }
00249               }
00250             }
00251           }
00252         }
00253       here2:
00254         if (flag) {
00255           ModEvent me = x1.include(home,iv[i].idx);
00256           GECODE_ME_CHECK(me);
00257           fix_flag=true;
00258         }
00259       }
00260     } while(fix_flag);
00261 
00262     return ES_FIX;
00263   }
00264 
00265 }}}
00266 
00267 // STATISTICS: set-prop