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

partition.icc

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  *  Contributing authors:
00008  *     Gabor Szokoli <szokoli@gecode.org>
00009  *
00010  *  Copyright:
00011  *     Guido Tack, 2004
00012  *     Christian Schulte, 2004
00013  *     Gabor Szokoli, 2004
00014  *
00015  *  Last modified:
00016  *     $Date: 2008-01-31 18:29:16 +0100 (Thu, 31 Jan 2008) $ by $Author: tack $
00017  *     $Revision: 6017 $
00018  *
00019  *  This file is part of Gecode, the generic constraint
00020  *  development environment:
00021  *     http://www.gecode.org
00022  *
00023  *  Permission is hereby granted, free of charge, to any person obtaining
00024  *  a copy of this software and associated documentation files (the
00025  *  "Software"), to deal in the Software without restriction, including
00026  *  without limitation the rights to use, copy, modify, merge, publish,
00027  *  distribute, sublicense, and/or sell copies of the Software, and to
00028  *  permit persons to whom the Software is furnished to do so, subject to
00029  *  the following conditions:
00030  *
00031  *  The above copyright notice and this permission notice shall be
00032  *  included in all copies or substantial portions of the Software.
00033  *
00034  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00035  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00036  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00037  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00038  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00039  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00040  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00041  *
00042  */
00043 
00044 namespace Gecode { namespace Set { namespace RelOp {
00045 
00046   /*
00047    * "Nary partition" propagator
00048    *
00049    */
00050 
00051   template <class View0, class View1>
00052   forceinline
00053   PartitionN<View0,View1>::PartitionN(Space* home, ViewArray<View0>& x, View1 y)
00054     : MixNaryOnePropagator<View0,PC_SET_ANY,View1,PC_SET_ANY>(home, x, y) {
00055     shared = x.shared() || viewarrayshared(x,y);
00056   }
00057 
00058   template <class View0, class View1>
00059   forceinline
00060   PartitionN<View0,View1>::PartitionN(Space* home, ViewArray<View0>& x,
00061                                       const IntSet& z, View1 y)
00062     : MixNaryOnePropagator<View0,PC_SET_ANY,View1,PC_SET_ANY>(home, x, y) {
00063     shared = x.shared() || viewarrayshared(x,y);
00064     IntSetRanges rz(z);
00065     unionOfDets.includeI(home, rz);
00066   }
00067 
00068   template <class View0, class View1>
00069   forceinline
00070   PartitionN<View0,View1>::PartitionN(Space* home, bool share, PartitionN& p)
00071     : MixNaryOnePropagator<View0,PC_SET_ANY,View1,PC_SET_ANY>(home,share,p),
00072       shared(p.shared) {
00073     unionOfDets.update(home,p.unionOfDets);
00074   }
00075 
00076   template <class View0, class View1>
00077   Actor*
00078   PartitionN<View0,View1>::copy(Space* home, bool share) {
00079     return new (home) PartitionN(home,share,*this);
00080   }
00081 
00082   template <class View0, class View1>
00083   Support::Symbol
00084   PartitionN<View0,View1>::ati(void) {
00085     return Reflection::mangle<View0,View1>("Gecode::Set::RelOp::PartitionN");
00086   }
00087 
00088   template <class View0, class View1>
00089   Reflection::ActorSpec
00090   PartitionN<View0,View1>::spec(const Space* home,
00091                                 Reflection::VarMap& m) const {
00092     Reflection::ActorSpec s =
00093       MixNaryOnePropagator<View0,PC_SET_ANY,View1,PC_SET_ANY>
00094         ::spec(home, m, ati());
00095     int count = 0;
00096     for (BndSetRanges uod(unionOfDets); uod(); ++uod)
00097       count++;
00098     Reflection::IntArrayArg* a = Reflection::Arg::newIntArray(count*2);
00099     count = 0;
00100     for (BndSetRanges uod(unionOfDets); uod(); ++uod) {
00101       (*a)[count++] = uod.min();
00102       (*a)[count++] = uod.max();
00103     }
00104     return s << a;
00105   }
00106 
00107   template <class View0, class View1>
00108   void
00109   PartitionN<View0,View1>::post(Space* home,
00110                                 Reflection::VarMap& vars,
00111                                 const Reflection::ActorSpec& spec) {
00112     spec.checkArity(3);
00113     ViewArray<View0> x0(home, vars, spec[0]);
00114     View1 x1(home, vars, spec[1]);
00115     Reflection::IntArrayArgRanges zr(spec[2]->toIntArray());
00116     IntSet z(zr);
00117     (void) new (home) PartitionN(home,x0,z,x1);
00118   }
00119 
00120   template <class View0, class View1>
00121   ExecStatus PartitionN<View0,View1>::post(Space* home, ViewArray<View0>& x,
00122                                            View1 y) {
00123     switch (x.size()) {
00124     case 0:
00125       GECODE_ME_CHECK(y.cardMax(home, 0));
00126       return ES_OK;
00127     case 1:
00128       return Rel::Eq<View0,View1>::post(home, x[0], y);
00129     default:
00130       (void) new (home) PartitionN<View0,View1>(home,x,y);
00131       return ES_OK;
00132     }
00133   }
00134 
00135   template <class View0, class View1>
00136   ExecStatus PartitionN<View0,View1>::post(Space* home, ViewArray<View0>& x,
00137                                            const IntSet& z, View1 y) {
00138     (void) new (home) PartitionN<View0,View1>(home,x,z,y);
00139     return ES_OK;
00140   }
00141 
00142   template <class View0, class View1>
00143   PropCost PartitionN<View0,View1>::cost(ModEventDelta) const {
00144     return PC_QUADRATIC_LO;
00145   }
00146 
00147   template <class View0, class View1>
00148   ExecStatus
00149   PartitionN<View0,View1>::propagate(Space* home, ModEventDelta med) {
00150 
00151     ModEvent me0 = View0::me(med);
00152     ModEvent me1 = View1::me(med);
00153     bool ubevent = Rel::testSetEventUB(me0, me1);
00154     bool lbevent = Rel::testSetEventLB(me0, me1);
00155     bool anybevent = Rel::testSetEventAnyB(me0, me1);
00156     bool cardevent = Rel::testSetEventCard(me0, me1);
00157 
00158     bool modified = false;
00159     bool oldModified = false;
00160 
00161     do {
00162       oldModified = modified;
00163       modified = false;
00164       if (oldModified || anybevent)
00165         GECODE_ME_CHECK(partitionNXiUB(home,modified, x, y,unionOfDets));
00166       if (modified || oldModified || anybevent)
00167         GECODE_ME_CHECK(partitionNXiLB(home,modified, x, y,unionOfDets));
00168       if (modified || oldModified || ubevent)
00169         GECODE_ME_CHECK(partitionNYUB(home,modified, x, y,unionOfDets));
00170       if (modified || oldModified || lbevent)
00171         GECODE_ME_CHECK(partitionNYLB(home,modified, x, y,unionOfDets));
00172       if (modified || oldModified || ubevent)
00173         GECODE_ME_CHECK(unionNXiUB(home,modified, x, y,unionOfDets));
00174       if (modified || oldModified || cardevent)
00175         GECODE_ME_CHECK(partitionNCard(home,modified, x, y,unionOfDets));
00176     } while (modified);
00177 
00178     //removing assigned sets from x, accumulating the value:
00179     for(int i=0;i<x.size();i++){
00180       //Do not reverse! Eats away the end of the array!
00181       while (i<x.size() && x[i].assigned()) {
00182         GlbRanges<View0> det(x[i]);
00183         unionOfDets.includeI(home,det);
00184         x.move_lst(i);
00185       }
00186     }
00187     // When we run out of variables, make a final check and disolve:
00188     if (x.size()==0) {
00189       BndSetRanges all1(unionOfDets);
00190       GECODE_ME_CHECK( y.intersectI(home,all1) );
00191       BndSetRanges all2(unionOfDets);
00192       GECODE_ME_CHECK( y.includeI(home,all2) );
00193       unionOfDets.dispose(home);
00194       return ES_SUBSUMED(this,home);
00195     }
00196 
00197     return shared ? ES_NOFIX : ES_FIX;
00198   }
00199 
00200 }}}
00201 
00202 // STATISTICS: set-prop