00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 namespace Gecode { namespace Float { namespace Arithmetic {
00041
00042 #include <cmath>
00043
00044
00045
00046
00047 template<class A, class B, class C>
00048 forceinline
00049 Min<A,B,C>::Min(Home home, A x0, B x1, C x2)
00050 : MixTernaryPropagator<A,PC_FLOAT_BND,B,PC_FLOAT_BND,C,PC_FLOAT_BND>(home,x0,x1,x2) {}
00051
00052 template<class A, class B, class C>
00053 forceinline
00054 Min<A,B,C>::Min(Space& home, bool share, Min<A,B,C>& p)
00055 : MixTernaryPropagator<A,PC_FLOAT_BND,B,PC_FLOAT_BND,C,PC_FLOAT_BND>(home,share,p) {}
00056
00057 template<class A, class B, class C>
00058 forceinline
00059 Min<A,B,C>::Min(Space& home, bool share, Propagator& p,
00060 A x0, B x1, C x2)
00061 : MixTernaryPropagator<A,PC_FLOAT_BND,B,PC_FLOAT_BND,C,PC_FLOAT_BND>(home,share,p,x0,x1,x2) {}
00062
00063 template<class A, class B, class C>
00064 Actor*
00065 Min<A,B,C>::copy(Space& home, bool share) {
00066 return new (home) Min<A,B,C>(home,share,*this);
00067 }
00068
00069 template<class A, class B, class C>
00070 ExecStatus
00071 Min<A,B,C>::post(Home home, A x0, B x1, C x2) {
00072 (void) new (home) Min<A,B,C>(home,x0,x1,x2);
00073 return ES_OK;
00074 }
00075
00076 template<class A, class B, class C>
00077 ExecStatus
00078 Min<A,B,C>::propagate(Space& home, const ModEventDelta&) {
00079 GECODE_ME_CHECK(x2.eq(home,min(x0.domain(),x1.domain())));
00080 GECODE_ME_CHECK(x0.gq(home,x2.min()));
00081 GECODE_ME_CHECK(x1.gq(home,x2.min()));
00082 if (same(x0,x1)) {
00083 GECODE_ME_CHECK(x0.lq(home,x2.max()));
00084 } else {
00085 if (!overlap(x1.val(),x2.val())) GECODE_ME_CHECK(x0.lq(home,x2.max()));
00086 if (!overlap(x0.val(),x2.val())) GECODE_ME_CHECK(x1.lq(home,x2.max()));
00087 }
00088 return (x0.assigned() && x1.assigned()) ? home.ES_SUBSUMED(*this) : ES_FIX;
00089 }
00090
00091
00092
00093
00094
00095
00096 template<class A, class B, class C>
00097 forceinline
00098 Max<A,B,C>::Max(Home home, A x0, B x1, C x2)
00099 : MixTernaryPropagator<A,PC_FLOAT_BND,B,PC_FLOAT_BND,C,PC_FLOAT_BND>(home,x0,x1,x2) {}
00100
00101 template<class A, class B, class C>
00102 forceinline
00103 Max<A,B,C>::Max(Space& home, bool share, Max<A,B,C>& p)
00104 : MixTernaryPropagator<A,PC_FLOAT_BND,B,PC_FLOAT_BND,C,PC_FLOAT_BND>(home,share,p) {}
00105
00106 template<class A, class B, class C>
00107 forceinline
00108 Max<A,B,C>::Max(Space& home, bool share, Propagator& p,
00109 A x0, B x1, C x2)
00110 : MixTernaryPropagator<A,PC_FLOAT_BND,B,PC_FLOAT_BND,C,PC_FLOAT_BND>(home,share,p,x0,x1,x2) {}
00111
00112 template<class A, class B, class C>
00113 Actor*
00114 Max<A,B,C>::copy(Space& home, bool share) {
00115 return new (home) Max<A,B,C>(home,share,*this);
00116 }
00117
00118 template<class A, class B, class C>
00119 ExecStatus
00120 Max<A,B,C>::post(Home home, A x0, B x1, C x2) {
00121 (void) new (home) Max<A,B,C>(home,x0,x1,x2);
00122 return ES_OK;
00123 }
00124
00125 template<class A, class B, class C>
00126 ExecStatus
00127 Max<A,B,C>::propagate(Space& home, const ModEventDelta&) {
00128 GECODE_ME_CHECK(x2.eq(home,max(x0.domain(),x1.domain())));
00129 GECODE_ME_CHECK(x0.lq(home,x2.max()));
00130 GECODE_ME_CHECK(x1.lq(home,x2.max()));
00131 if (same(x0,x1)) {
00132 GECODE_ME_CHECK(x0.gq(home,x2.min()));
00133 } else {
00134 if (!overlap(x1.val(),x2.val())) GECODE_ME_CHECK(x0.gq(home,x2.min()));
00135 if (!overlap(x0.val(),x2.val())) GECODE_ME_CHECK(x1.gq(home,x2.min()));
00136 }
00137 return (x0.assigned() && x1.assigned()) ? home.ES_SUBSUMED(*this) : ES_FIX;
00138 }
00139
00140
00141
00142
00143
00144
00145 template<class View>
00146 forceinline
00147 NaryMax<View>::NaryMax(Home home, ViewArray<View>& x, View y)
00148 : NaryOnePropagator<View,PC_FLOAT_BND>(home,x,y) {}
00149
00150 template<class View>
00151 ExecStatus
00152 NaryMax<View>::post(Home home, ViewArray<View>& x, View y) {
00153 assert(x.size() > 0);
00154 x.unique(home);
00155 if (x.size() == 1)
00156 return Rel::Eq<View,View>::post(home,x[0],y);
00157 if (x.size() == 2)
00158 return Max<View,View,View>::post(home,x[0],x[1],y);
00159 FloatNum l = Float::Limits::min;
00160 FloatNum u = Float::Limits::min;
00161 for (int i=x.size(); i--; ) {
00162 l = std::max(l,x[i].min());
00163 u = std::max(u,x[i].max());
00164 }
00165 GECODE_ME_CHECK(y.gq(home,l));
00166 GECODE_ME_CHECK(y.lq(home,u));
00167 if (x.same(home,y)) {
00168
00169 for (int i=x.size(); i--; )
00170 GECODE_ES_CHECK((Rel::Lq<View>::post(home,x[i],y)));
00171 } else {
00172 (void) new (home) NaryMax<View>(home,x,y);
00173 }
00174 return ES_OK;
00175 }
00176
00177 template<class View>
00178 forceinline
00179 NaryMax<View>::NaryMax(Space& home, bool share, NaryMax<View>& p)
00180 : NaryOnePropagator<View,PC_FLOAT_BND>(home,share,p) {}
00181
00182 template<class View>
00183 Actor*
00184 NaryMax<View>::copy(Space& home, bool share) {
00185 if (x.size() == 1)
00186 return new (home) Rel::Eq<View,View>(home,share,*this,x[0],y);
00187 if (x.size() == 2)
00188 return new (home) Max<View,View,View>(home,share,*this,x[0],x[1],y);
00189 return new (home) NaryMax<View>(home,share,*this);
00190 }
00191
00193 enum MaxPropStatus {
00194 MPS_ASSIGNED = 1<<0,
00195 MPS_REMOVED = 1<<1,
00196 MPS_NEW_BOUND = 1<<2
00197 };
00198
00199 template<class View>
00200 forceinline ExecStatus
00201 prop_nary_max(Space& home, Propagator& p,
00202 ViewArray<View>& x, View y, PropCond pc) {
00203 rerun:
00204 assert(x.size() > 0);
00205 FloatNum maxmax = x[x.size()-1].max();
00206 FloatNum maxmin = x[x.size()-1].min();
00207 for (int i = x.size()-1; i--; ) {
00208 maxmax = std::max(x[i].max(),maxmax);
00209 maxmin = std::max(x[i].min(),maxmin);
00210 }
00211 GECODE_ME_CHECK(y.lq(home,maxmax));
00212 GECODE_ME_CHECK(y.gq(home,maxmin));
00213 maxmin = y.min();
00214 maxmax = y.max();
00215 int status = MPS_ASSIGNED;
00216 for (int i = x.size(); i--; ) {
00217 ModEvent me = x[i].lq(home,maxmax);
00218 if (me == ME_FLOAT_FAILED)
00219 return ES_FAILED;
00220 if (me_modified(me) && (x[i].max() != maxmax))
00221 status |= MPS_NEW_BOUND;
00222 if (x[i].max() < maxmin) {
00223 x.move_lst(i,home,p,pc);
00224 status |= MPS_REMOVED;
00225 } else if (!x[i].assigned())
00226 status &= ~MPS_ASSIGNED;
00227 }
00228 if (x.size() == 0)
00229 return ES_FAILED;
00230 if ((status & MPS_REMOVED) != 0)
00231 goto rerun;
00232 if (((status & MPS_ASSIGNED) != 0) && y.assigned())
00233 return home.ES_SUBSUMED(p);
00234 return ((status & MPS_NEW_BOUND) != 0) ? ES_NOFIX : ES_FIX;
00235 }
00236
00237 template<class View>
00238 ExecStatus
00239 NaryMax<View>::propagate(Space& home, const ModEventDelta&) {
00240 return prop_nary_max(home,*this,x,y,PC_FLOAT_BND);
00241 }
00242
00243
00244
00245
00246
00247
00248
00249 template<class A, class B>
00250 forceinline
00251 Channel<A,B>::Channel(Home home, A x0, B x1)
00252 : MixBinaryPropagator<A,PC_FLOAT_BND,B,Int::PC_INT_BND>(home,x0,x1) {}
00253
00254 template<class A, class B>
00255 forceinline
00256 Channel<A,B>::Channel(Space& home, bool share, Channel<A,B>& p)
00257 : MixBinaryPropagator<A,PC_FLOAT_BND,B,Int::PC_INT_BND>(home,share,p) {}
00258
00259 template<class A, class B>
00260 Actor*
00261 Channel<A,B>::copy(Space& home, bool share) {
00262 return new (home) Channel<A,B>(home,share,*this);
00263 }
00264
00265 template<class A, class B>
00266 ExecStatus
00267 Channel<A,B>::post(Home home, A x0, B x1) {
00268 GECODE_ME_CHECK(x0.eq(home,FloatVal(Int::Limits::min,
00269 Int::Limits::max)));
00270 (void) new (home) Channel<A,B>(home,x0,x1);
00271 return ES_OK;
00272 }
00273
00274 template<class A, class B>
00275 ExecStatus
00276 Channel<A,B>::propagate(Space& home, const ModEventDelta&) {
00277 GECODE_ME_CHECK(x1.gq(home,static_cast<int>(std::ceil(x0.min()))));
00278 GECODE_ME_CHECK(x1.lq(home,static_cast<int>(std::floor(x0.max()))));
00279 GECODE_ME_CHECK(x0.eq(home,FloatVal(x1.min(),x1.max())));
00280 return x0.assigned() ? home.ES_SUBSUMED(*this) : ES_FIX;
00281 }
00282
00283 }}}
00284
00285
00286