Generated on Thu Mar 22 10:39:44 2012 for Gecode by doxygen 1.6.3

partition.hpp

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: 2011-05-23 16:48:31 +0200 (Mon, 23 May 2011) $ by $Author: tack $
00017  *     $Revision: 12018 $
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(Home home, ViewArray<View0>& x, View1 y)
00054     : MixNaryOnePropagator<View0,PC_SET_ANY,View1,PC_SET_ANY>(home, x, y) {
00055     shared = x.shared(home) || viewarrayshared(home,x,y);
00056   }
00057 
00058   template<class View0, class View1>
00059   forceinline
00060   PartitionN<View0,View1>::PartitionN(Home 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(home) || viewarrayshared(home,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   ExecStatus PartitionN<View0,View1>::post(Home home, ViewArray<View0>& x,
00084                                            View1 y) {
00085     switch (x.size()) {
00086     case 0:
00087       GECODE_ME_CHECK(y.cardMax(home, 0));
00088       return ES_OK;
00089     case 1:
00090       return Rel::Eq<View0,View1>::post(home, x[0], y);
00091     default:
00092       (void) new (home) PartitionN<View0,View1>(home,x,y);
00093       return ES_OK;
00094     }
00095   }
00096 
00097   template<class View0, class View1>
00098   ExecStatus PartitionN<View0,View1>::post(Home home, ViewArray<View0>& x,
00099                                            const IntSet& z, View1 y) {
00100     (void) new (home) PartitionN<View0,View1>(home,x,z,y);
00101     return ES_OK;
00102   }
00103 
00104   template<class View0, class View1>
00105   PropCost PartitionN<View0,View1>::cost(const Space&, const ModEventDelta&) const {
00106     return PropCost::quadratic(PropCost::LO, x.size()+1);
00107   }
00108 
00109   template<class View0, class View1>
00110   ExecStatus
00111   PartitionN<View0,View1>::propagate(Space& home, const ModEventDelta& med) {
00112 
00113     ModEvent me0 = View0::me(med);
00114     ModEvent me1 = View1::me(med);
00115     bool ubevent = Rel::testSetEventUB(me0, me1);
00116     bool lbevent = Rel::testSetEventLB(me0, me1);
00117     bool anybevent = Rel::testSetEventAnyB(me0, me1);
00118     bool cardevent = Rel::testSetEventCard(me0, me1);
00119 
00120     bool modified = false;
00121     bool oldModified = false;
00122 
00123     do {
00124       oldModified = modified;
00125       modified = false;
00126       if (oldModified || anybevent)
00127         GECODE_ES_CHECK(partitionNXiUB(home,modified, x, y,unionOfDets));
00128       if (modified || oldModified || anybevent)
00129         GECODE_ES_CHECK(partitionNXiLB(home,modified, x, y,unionOfDets));
00130       if (modified || oldModified || ubevent)
00131         GECODE_ES_CHECK(partitionNYUB(home,modified, x, y,unionOfDets));
00132       if (modified || oldModified || lbevent)
00133         GECODE_ES_CHECK(partitionNYLB(home,modified, x, y,unionOfDets));
00134       if (modified || oldModified || ubevent)
00135         GECODE_ES_CHECK(unionNXiUB(home,modified, x, y,unionOfDets));
00136       if (modified || oldModified || cardevent)
00137         GECODE_ES_CHECK(partitionNCard(home,modified, x, y,unionOfDets));
00138     } while (modified);
00139 
00140     //removing assigned sets from x, accumulating the value:
00141     for(int i=0;i<x.size();i++){
00142       //Do not reverse! Eats away the end of the array!
00143       while (i<x.size() && x[i].assigned()) {
00144         GlbRanges<View0> det(x[i]);
00145         unionOfDets.includeI(home,det);
00146         x.move_lst(i);
00147       }
00148     }
00149     // When we run out of variables, make a final check and disolve:
00150     if (x.size()==0) {
00151       BndSetRanges all1(unionOfDets);
00152       GECODE_ME_CHECK( y.intersectI(home,all1) );
00153       BndSetRanges all2(unionOfDets);
00154       GECODE_ME_CHECK( y.includeI(home,all2) );
00155       unionOfDets.dispose(home);
00156       return home.ES_SUBSUMED(*this);
00157     }
00158 
00159     return shared ? ES_NOFIX : ES_FIX;
00160   }
00161 
00162 }}}
00163 
00164 // STATISTICS: set-prop