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

max.icc

Go to the documentation of this file.
00001 /*
00002  *  Main authors:
00003  *     Christian Schulte <schulte@gecode.org>
00004  *
00005  *  Copyright:
00006  *     Christian Schulte, 2004
00007  *
00008  *  Last modified:
00009  *     $Date: 2006-08-04 16:03:26 +0200 (Fri, 04 Aug 2006) $ by $Author: schulte $
00010  *     $Revision: 3512 $
00011  *
00012  *  This file is part of Gecode, the generic constraint
00013  *  development environment:
00014  *     http://www.gecode.org
00015  *
00016  *  See the file "LICENSE" for information on usage and
00017  *  redistribution of this file, and for a
00018  *     DISCLAIMER OF ALL WARRANTIES.
00019  *
00020  */
00021 
00022 #include "gecode/int/rel.hh"
00023 
00024 namespace Gecode { namespace Int { namespace Arithmetic {
00025 
00026   /*
00027    * Ternary bounds-consistent maximum
00028    *
00029    */
00030 
00031   template <class View>
00032   forceinline
00033   Max<View>::Max(Space* home, View x0, View x1, View x2)
00034     : TernaryPropagator<View,PC_INT_BND>(home,x0,x1,x2) {}
00035 
00036   template <class View>
00037   ExecStatus
00038   Max<View>::post(Space* home, View x0, View x1, View x2) {
00039     if (same(x0,x1))
00040       return Rel::EqBnd<View,View>::post(home,x0,x2);
00041     if (same(x0,x2))
00042       return Rel::Lq<View>::post(home,x1,x2);
00043     if (same(x1,x2))
00044       return Rel::Lq<View>::post(home,x0,x2);
00045     (void) new (home) Max<View>(home,x0,x1,x2);
00046     return ES_OK;
00047   }
00048 
00049   template <class View>
00050   forceinline
00051   Max<View>::Max(Space* home, bool share, Max<View>& p)
00052     : TernaryPropagator<View,PC_INT_BND>(home,share,p) {}
00053 
00054   template <class View>
00055   forceinline
00056   Max<View>::Max(Space* home, bool share, Propagator& p,
00057                  View x0, View x1, View x2)
00058     : TernaryPropagator<View,PC_INT_BND>(home,share,p,x0,x1,x2) {}
00059 
00060   template <class View>
00061   Actor*
00062   Max<View>::copy(Space* home, bool share) {
00063     return new (home) Max<View>(home,share,*this);
00064   }
00065 
00066   template <class View>
00067   ExecStatus
00068   Max<View>::propagate(Space* home) {
00069     bool mod = false;
00070     do {
00071       mod = false;
00072       {
00073         ModEvent me = x2.lq(home,std::max(x0.max(),x1.max()));
00074         if (me_failed(me)) return ES_FAILED;
00075         mod |= me_modified(me);
00076       }
00077       {
00078         ModEvent me = x2.gq(home,std::max(x0.min(),x1.min()));
00079         if (me_failed(me)) return ES_FAILED;
00080         mod |= me_modified(me);
00081       }
00082       {
00083         ModEvent me = x0.lq(home,x2.max());
00084         if (me_failed(me)) return ES_FAILED;
00085         mod |= me_modified(me);
00086       }
00087       {
00088         ModEvent me = x1.lq(home,x2.max());
00089         if (me_failed(me)) return ES_FAILED;
00090         mod |= me_modified(me);
00091       }
00092     } while (mod);
00093     if (x0.max() <= x1.min()) {
00094       GECODE_ES_CHECK((Rel::EqBnd<View,View>::post(home,x1,x2)));
00095       return ES_SUBSUMED;
00096     }
00097     if (x1.max() <= x0.min()) {
00098       GECODE_ES_CHECK((Rel::EqBnd<View,View>::post(home,x0,x2)));
00099       return ES_SUBSUMED;
00100     }
00101     return x0.assigned() && x1.assigned() && x2.assigned() ? ES_SUBSUMED : ES_FIX;
00102   }
00103 
00104 
00105 
00106   /*
00107    * Nary bounds-consistent maximum
00108    *
00109    */
00110 
00111   template <class View>
00112   forceinline
00113   NaryMax<View>::NaryMax(Space* home, ViewArray<View>& x, View y)
00114     : NaryOnePropagator<View,PC_INT_BND>(home,x,y) {}
00115 
00116   template <class View>
00117   ExecStatus
00118   NaryMax<View>::post(Space* home, ViewArray<View>& x, View y) {
00119     assert(x.size() > 0);
00120     x.unique();
00121     if (x.size() == 1)
00122       return Rel::EqBnd<View,View>::post(home,x[0],y);
00123     if (x.size() == 2)
00124       return Max<View>::post(home,x[0],x[1],y);
00125     if (x.same(y)) {
00126       // Check whether y occurs in x
00127       for (int i=x.size(); i--; )
00128         GECODE_ES_CHECK(Rel::Lq<View>::post(home,x[i],y));
00129     } else {
00130       (void) new (home) NaryMax<View>(home,x,y);
00131     }
00132     return ES_OK;
00133   }
00134 
00135   template <class View>
00136   forceinline
00137   NaryMax<View>::NaryMax(Space* home, bool share, NaryMax<View>& p)
00138     : NaryOnePropagator<View,PC_INT_BND>(home,share,p) {}
00139 
00140   template <class View>
00141   Actor*
00142   NaryMax<View>::copy(Space* home, bool share) {
00143     if (x.size() == 1)
00144       return new (home) Rel::EqBnd<View,View>(home,share,*this,x[0],y);
00145     if (x.size() == 2)
00146       return new (home) Max<View>(home,share,*this,x[0],x[1],y);
00147     return new (home) NaryMax<View>(home,share,*this);
00148   }
00149 
00151   enum MaxPropStatus {
00152     MPS_ASSIGNED  = 1<<0, 
00153     MPS_REMOVED   = 1<<1, 
00154     MPS_NEW_BOUND = 1<<2  
00155   };
00156 
00157   template <class View>
00158   ExecStatus
00159   NaryMax<View>::propagate(Space* home) {
00160   rerun:
00161     int maxmax = Limits::Int::int_min-1;
00162     int maxmin = Limits::Int::int_min-1;
00163     for (int i = x.size(); i--; ) {
00164       maxmax = std::max(x[i].max(),maxmax);
00165       maxmin = std::max(x[i].min(),maxmin);
00166     }
00167     GECODE_ME_CHECK(y.lq(home,maxmax));
00168     GECODE_ME_CHECK(y.gq(home,maxmin));
00169     maxmin = y.min();
00170     maxmax = y.max();
00171     int status = MPS_ASSIGNED;
00172     for (int i = x.size(); i--; ) {
00173       ModEvent me = x[i].lq(home,maxmax);
00174       if (me == ME_INT_FAILED)
00175         return ES_FAILED;
00176       if (me_modified(me) && (x[i].max() != maxmax))
00177         status |= MPS_NEW_BOUND;
00178       if (x[i].max() < maxmin) {
00179         x.move_lst(i,home,this,PC_INT_BND);
00180         status |= MPS_REMOVED;
00181       } else if (!x[i].assigned())
00182         status &= ~MPS_ASSIGNED;
00183     }
00184     if (x.size() == 0)
00185       return ES_FAILED;
00186     if ((status & MPS_REMOVED) != 0)
00187       goto rerun;
00188     if (((status & MPS_ASSIGNED) != 0) && y.assigned())
00189       return ES_SUBSUMED;
00190     return ((status & MPS_NEW_BOUND) != 0) ? ES_NOFIX : ES_FIX;
00191   }
00192 
00193 }}}
00194 
00195 // STATISTICS: int-prop
00196