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

disjoint.cc

Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
00002 /*
00003  *  Main authors:
00004  *     Guido Tack <tack@gecode.org>
00005  *     Christian Schulte <schulte@gecode.org>
00006  *
00007  *  Copyright:
00008  *     Guido Tack, 2004
00009  *     Christian Schulte, 2004
00010  *
00011  *  Last modified:
00012  *     $Date: 2008-05-27 19:24:07 +0200 (Tue, 27 May 2008) $ by $Author: tack $
00013  *     $Revision: 6982 $
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/set/element.hh"
00041 #include "gecode/set/rel.hh"
00042 #include "gecode/set/rel-op.hh"
00043 
00044 namespace Gecode { namespace Set { namespace Element {
00045 
00046   PropCost
00047   ElementDisjoint::cost(ModEventDelta) const {
00048     return PC_QUADRATIC_LO;
00049   }
00050 
00051   Support::Symbol
00052   ElementDisjoint::ati(void) {
00053     return Support::Symbol("Gecode::Set::Element::Disjoint");
00054   }
00055 
00056   Reflection::ActorSpec
00057   ElementDisjoint::spec(const Space* home, Reflection::VarMap& m) const {
00058     Reflection::ActorSpec s(ati());
00059     return s << iv.spec(home, m) << x1.spec(home, m);
00060   }
00061 
00062   void
00063   ElementDisjoint::post(Space* home, Reflection::VarMap& vars,
00064                        const Reflection::ActorSpec& spec) {
00065     spec.checkArity(2);
00066     IdxViewArray<SetView> iv(home, vars, spec[0]);
00067     SetView x1(home, vars, spec[1]);
00068     (void) new (home) ElementDisjoint(home, iv, x1);
00069   }
00070 
00071   size_t
00072   ElementDisjoint::dispose(Space* home) {
00073     assert(!home->failed());
00074     x1.cancel(home,this, PC_SET_ANY);
00075     iv.cancel(home,this,PC_SET_ANY);
00076     (void) Propagator::dispose(home);
00077     return sizeof(*this);
00078   }
00079 
00080   Actor*
00081   ElementDisjoint::copy(Space* home, bool share) {
00082     return new (home) ElementDisjoint(home,share,*this);
00083   }
00084 
00085   ExecStatus
00086   ElementDisjoint::propagate(Space* home, ModEventDelta) {
00087     int n = iv.size();
00088 
00089     bool fix_flag = false;
00090     do {
00091       fix_flag = false;
00092       // Compute union of all selected elements' lower bounds
00093       GlbRanges<SetView> x1lb(x1);
00094       Iter::Ranges::ToValues<GlbRanges<SetView> > vx1lb(x1lb);
00095       GLBndSet unionOfSelected(home);
00096       for(int i=0; vx1lb(); ++vx1lb) {
00097         while (iv[i].idx < vx1lb.val()) i++;
00098         GlbRanges<SetView> clb(iv[i].var);
00099         unionOfSelected.includeI(home,clb);
00100       }
00101 
00102       {
00103         LubRanges<SetView> x1ub(x1);
00104         Iter::Ranges::ToValues<LubRanges<SetView> > vx1ub(x1ub);
00105         int i=0;
00106         int j=0;
00107         // Cancel all elements that are no longer in the upper bound
00108         while (vx1ub()) {
00109           if (iv[i].idx < vx1ub.val()) {
00110             iv[i].var.cancel(home,this, PC_SET_ANY);
00111             i++;
00112             continue;
00113           }
00114           iv[j] = iv[i];
00115           ++vx1ub;
00116           ++i; ++j;
00117         }
00118 
00119         // cancel the variables with index greater than
00120         // max of lub(x1)
00121         for (int k=i; k<n; k++) {
00122           iv[k].var.cancel(home,this, PC_SET_ANY);
00123         }
00124         n = j;
00125         iv.size(n);
00126       }
00127 
00128       {
00129       UnknownRanges<SetView> x1u(x1);
00130       Iter::Ranges::Cache<UnknownRanges<SetView> > x1uc(x1u);
00131       Iter::Ranges::ToValues<Iter::Ranges::Cache<UnknownRanges<SetView> > >
00132         vx1u(x1uc);
00133       int i=0;
00134       int j=0;
00135       while (vx1u()) {
00136         while (iv[i].idx < vx1u.val()) {
00137           iv[j] = iv[i];
00138           i++; j++;
00139         }
00140         assert(iv[i].idx == vx1u.val());
00141 
00142         SetView candidate = iv[i].var;
00143         int candidateInd = iv[i].idx;
00144 
00145         GlbRanges<SetView> clb(candidate);
00146         BndSetRanges uos(unionOfSelected);
00147         Iter::Ranges::Inter<GlbRanges<SetView>, BndSetRanges>
00148           inter(clb, uos);
00149         if (inter()) {
00150           ModEvent me = x1.exclude(home,candidateInd);
00151           fix_flag |= me_modified(me);
00152           GECODE_ME_CHECK(me);
00153 
00154           candidate.cancel(home,this, PC_SET_ANY);
00155           ++i;
00156           ++vx1u;
00157           continue;
00158         }
00159         iv[j] = iv[i];
00160         ++vx1u;
00161         ++i; ++j;
00162       }
00163 
00164       unionOfSelected.dispose(home);
00165 
00166       // copy remaining variables
00167       for (int k=i; k<n; k++) {
00168         iv[j] = iv[k];
00169         j++;
00170       }
00171       n = j;
00172       iv.size(n);
00173       }
00174 
00175       if (x1.cardMax()==0) {
00176         // Selector is empty, we're done
00177         return ES_SUBSUMED(this,home);
00178       }
00179 
00180       {
00181         // remove all elements in a selected variable from
00182         // all other selected variables
00183         GlbRanges<SetView> x1lb(x1);
00184         Iter::Ranges::ToValues<GlbRanges<SetView> > vx1lb(x1lb);
00185         int i=0;
00186         for (; vx1lb(); ++vx1lb) {
00187           while (iv[i].idx < vx1lb.val()) i++;
00188           assert(iv[i].idx==vx1lb.val());
00189           GlbRanges<SetView> x1lb2(x1);
00190           Iter::Ranges::ToValues<GlbRanges<SetView> > vx1lb2(x1lb2);
00191           for (int j=0; vx1lb2(); ++vx1lb2) {
00192             while (iv[j].idx < vx1lb2.val()) j++;
00193             assert(iv[j].idx==vx1lb2.val());
00194             if (iv[i].idx!=iv[j].idx) {
00195               GlbRanges<SetView> xilb(iv[i].var);
00196               ModEvent me = iv[j].var.excludeI(home,xilb);
00197               fix_flag |= me_modified(me);
00198               GECODE_ME_CHECK(me);
00199             }
00200           }
00201         }
00202       }
00203 
00204       // remove all elements from the selector that overlap
00205       // with all other possibly selected elements, if
00206       // at least two more elements need to be selected
00207       if (x1.cardMin()-x1.glbSize() > 1) {
00208         UnknownRanges<SetView> x1u(x1);
00209         Iter::Ranges::Cache<UnknownRanges<SetView> > x1uc(x1u);
00210         Iter::Ranges::ToValues<Iter::Ranges::Cache<UnknownRanges<SetView> > >
00211           vx1u(x1uc);
00212 
00213         for (; vx1u() && x1.cardMin()-x1.glbSize() > 1; ++vx1u) {
00214           int i = 0;
00215           while (iv[i].idx < vx1u.val()) i++;
00216           assert(iv[i].idx == vx1u.val());
00217           bool flag=true;
00218 
00219           UnknownRanges<SetView> x1u2(x1);
00220           Iter::Ranges::ToValues<UnknownRanges<SetView> > vx1u2(x1u2);
00221           for (; vx1u2(); ++vx1u2) {
00222             int j = 0;
00223             while (iv[j].idx < vx1u2.val()) j++;
00224             assert(iv[j].idx == vx1u2.val());
00225             if (iv[i].idx!=iv[j].idx) {
00226               GlbRanges<SetView> xjlb(iv[j].var);
00227               GlbRanges<SetView> xilb(iv[i].var);
00228               Iter::Ranges::Inter<GlbRanges<SetView>, GlbRanges<SetView> >
00229                 inter(xjlb, xilb);
00230               if (!inter()) {
00231                 flag = false;
00232                 goto here;
00233               }
00234             }
00235           }
00236         here:
00237           if (flag) {
00238             ModEvent me = x1.exclude(home,iv[i].idx);
00239             fix_flag |= me_modified(me);
00240             GECODE_ME_CHECK(me);
00241           }
00242         }
00243       }
00244 
00245       // if exactly two more elements need to be selected
00246       // and there is a possible element i such that all other pairs of
00247       // elements overlap, select i
00248       UnknownRanges<SetView> x1u(x1);
00249       Iter::Ranges::Cache<UnknownRanges<SetView> > x1uc(x1u);
00250       Iter::Ranges::ToValues<Iter::Ranges::Cache<UnknownRanges<SetView> > >
00251         vx1u(x1uc);
00252 
00253       for (; x1.cardMin()-x1.glbSize() == 2 && vx1u(); ++vx1u) {
00254         int i = 0;
00255         while (iv[i].idx < vx1u.val()) i++;
00256         assert (iv[i].idx == vx1u.val());
00257         bool flag=true;
00258 
00259         UnknownRanges<SetView> x1u2(x1);
00260         Iter::Ranges::ToValues<UnknownRanges<SetView> > vx1u2(x1u2);
00261         for (; vx1u2(); ++vx1u2) {
00262           int j = 0;
00263           while (iv[j].idx < vx1u2.val()) j++;
00264           assert (iv[j].idx == vx1u2.val());
00265           if (iv[i].idx!=iv[j].idx) {
00266             UnknownRanges<SetView> x1u3(x1);
00267             Iter::Ranges::ToValues<UnknownRanges<SetView> > vx1u3(x1u3);
00268             for (; vx1u3(); ++vx1u3) {
00269               int k = 0;
00270               while (iv[k].idx < vx1u3.val()) k++;
00271               assert (iv[k].idx == vx1u3.val());
00272               if (iv[j].idx!=iv[k].idx && iv[i].idx!=iv[k].idx) {
00273                 GlbRanges<SetView> xjlb(iv[j].var);
00274                 GlbRanges<SetView> xilb(iv[k].var);
00275                 Iter::Ranges::Inter<GlbRanges<SetView>, GlbRanges<SetView> >
00276                   inter(xjlb, xilb);
00277                 if (!inter()) {
00278                   flag = false;
00279                   goto here2;
00280                 }
00281               }
00282             }
00283           }
00284         }
00285       here2:
00286         if (flag) {
00287           ModEvent me = x1.include(home,iv[i].idx);
00288           fix_flag |= me_modified(me);
00289           GECODE_ME_CHECK(me);
00290         }
00291       }
00292     } while (fix_flag);
00293 
00294     bool allAssigned = true;
00295     for (int i=iv.size(); i--;)
00296       if (!iv[i].var.assigned()) {
00297         allAssigned = false;
00298         break;
00299       }
00300     if (!x1.assigned())
00301       allAssigned = false;
00302 
00303     return allAssigned ? ES_SUBSUMED(this,home) : ES_FIX;
00304   }
00305 
00306 }}}
00307 
00308 // STATISTICS: set-prop