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
00041
00042 #include "gecode/set.hh"
00043 #include "gecode/int.hh"
00044
00045 namespace Gecode { namespace Set { namespace Int {
00046
00048 template <class I>
00049 class OverweightValues {
00050 private:
00052 int threshold;
00054 I iter;
00056 const SharedArray<int> elements;
00058 const SharedArray<int> weights;
00060 int index;
00062 void next(void);
00063 public:
00065
00066
00067 OverweightValues(void);
00069 OverweightValues(int t,
00070 SharedArray<int>& elements0,
00071 SharedArray<int>& weights0,
00072 I& i);
00074 void init(int t,
00075 SharedArray<int>& elements0,
00076 SharedArray<int>& weights0,
00077 I& i);
00079
00081
00082
00083 bool operator()(void) const;
00085 void operator++(void);
00087
00088
00089
00090 int val(void) const;
00092 };
00093
00094 template <class I>
00095 forceinline void
00096 OverweightValues<I>::next(void) {
00097 while (iter()) {
00098 while (elements[index]<iter.val()) index++;
00099 assert(elements[index]==iter.val());
00100 if (weights[index] > threshold) {
00101 return;
00102 }
00103 ++iter;
00104 }
00105 }
00106
00107 template <class I>
00108 forceinline
00109 OverweightValues<I>::OverweightValues(void) {}
00110
00111 template <class I>
00112 forceinline
00113 OverweightValues<I>::OverweightValues(int t,
00114 SharedArray<int>& elements0,
00115 SharedArray<int>& weights0,
00116 I& i) : threshold(t),
00117 iter(i),
00118 elements(elements0),
00119 weights(weights0),
00120 index(0) {
00121 next();
00122 }
00123
00124 template <class I>
00125 forceinline void
00126 OverweightValues<I>::init(int t,
00127 SharedArray<int>& elements0,
00128 SharedArray<int>& weights0,
00129 I& i) {
00130 threshold = t; iter = i;
00131 elements = elements0; weights = weights0;
00132 index = 0;
00133 next();
00134 }
00135
00136 template <class I>
00137 forceinline bool
00138 OverweightValues<I>::operator()(void) const { return iter(); }
00139
00140 template <class I>
00141 forceinline void
00142 OverweightValues<I>::operator++(void) { ++iter; next(); }
00143
00144 template <class I>
00145 forceinline int
00146 OverweightValues<I>::val(void) const { return elements[index]; }
00147
00148 template <class View>
00149 forceinline
00150 Weights<View>::Weights(Space* home,
00151 const IntArgs& elements0, const IntArgs& weights0,
00152 View x0, Gecode::Int::IntView y0)
00153 : Propagator(home), elements(elements0.size()), weights(weights0.size()),
00154 x(x0), y(y0) {
00155 x.subscribe(home,this, PC_SET_ANY);
00156 y.subscribe(home,this, Gecode::Int::PC_INT_BND);
00157 for (int i=elements0.size(); i--;) {
00158 elements[i] = elements0[i];
00159 weights[i] = weights0[i];
00160 }
00161 }
00162
00163 template <class View>
00164 forceinline
00165 Weights<View>::Weights(Space* home, bool share, Weights& p)
00166 : Propagator(home,share,p) {
00167 x.update(home,share,p.x);
00168 y.update(home,share,p.y);
00169 elements.update(home,share,p.elements);
00170 weights.update(home,share,p.weights);
00171 }
00172
00173 template <class View>
00174 inline ExecStatus
00175 Weights<View>::post(Space* home, const IntArgs& elements, const IntArgs& weights,
00176 View x, Gecode::Int::IntView y) {
00177 if (elements.size() != weights.size())
00178 throw ArgumentSizeMismatch("Weights");
00179 GECODE_AUTOARRAY(int, els_arr, elements.size());
00180 for (int i=elements.size(); i--;)
00181 els_arr[i] = elements[i];
00182 IntSet els(els_arr, elements.size());
00183 IntSetRanges er(els);
00184 GECODE_ME_CHECK(x.intersectI(home, er));
00185 (void) new (home) Weights(home,elements,weights,x,y);
00186 return ES_OK;
00187 }
00188
00189 template <class View>
00190 PropCost
00191 Weights<View>::cost(ModEventDelta) const {
00192 return PC_LINEAR_LO;
00193 }
00194
00195 template <class View>
00196 size_t
00197 Weights<View>::dispose(Space* home) {
00198 assert(!home->failed());
00199 x.cancel(home,this, PC_SET_ANY);
00200 y.cancel(home,this, Gecode::Int::PC_INT_BND);
00201 (void) Propagator::dispose(home);
00202 return sizeof(*this);
00203 }
00204
00205 template <class View>
00206 Actor*
00207 Weights<View>::copy(Space* home, bool share) {
00208 return new (home) Weights(home,share,*this);
00209 }
00210
00211 enum CostType { POS_COST, NEG_COST, ALL_COST };
00212
00213 template <class I, CostType c>
00214 forceinline
00215 int weightI(SharedArray<int>& elements,
00216 SharedArray<int>& weights,
00217 I& iter) {
00218 int sum = 0;
00219 int i = 0;
00220 for (Iter::Ranges::ToValues<I> v(iter); v(); ++v) {
00221
00222 while (elements[i]<v.val()) i++;
00223 assert(elements[i] == v.val());
00224 switch (c) {
00225 case ALL_COST:
00226 sum += weights[i];
00227 break;
00228 case POS_COST:
00229 if (weights[i] > 0) sum += weights[i];
00230 break;
00231 case NEG_COST:
00232 if (weights[i] < 0) sum += weights[i];
00233 break;
00234 default: GECODE_NEVER;
00235 }
00236 }
00237 return sum;
00238 }
00239
00240
00242 class IntLt {
00243 public:
00244 bool operator()(int x, int y);
00245 };
00246
00247 forceinline bool
00248 IntLt::operator()(int x, int y) {
00249 return x < y;
00250 }
00251
00252 template <class View>
00253 ExecStatus
00254 Weights<View>::propagate(Space* home, ModEventDelta) {
00255
00256 if (x.assigned()) {
00257 GlbRanges<View> glb(x);
00258 int w =
00259 weightI<GlbRanges<View>,ALL_COST>(elements, weights, glb);
00260 GECODE_ME_CHECK(y.eq(home, w));
00261 return ES_SUBSUMED(this,home);
00262 }
00263
00264 int lowCost;
00265 int lowestCost;
00266 int highestCost;
00267 int size = elements.size();
00268 {
00269 UnknownRanges<View> ur(x);
00270 Iter::Ranges::ToValues<UnknownRanges<View> > urv(ur);
00271 GECODE_AUTOARRAY(int, currentWeights, size);
00272 for (int i=0; i<size; i++) {
00273 if (!urv() || elements[i]<urv.val()) {
00274 currentWeights[i] = 0;
00275 } else {
00276 assert(elements[i] == urv.val());
00277 currentWeights[i] = weights[i];
00278 ++urv;
00279 }
00280 }
00281
00282 IntLt ilt;
00283 Support::quicksort<int>(currentWeights, size, ilt);
00284
00285 GlbRanges<View> glb(x);
00286 lowCost = weightI<GlbRanges<View>,ALL_COST>(elements, weights, glb);
00287 highestCost =
00288 weightI<GlbRanges<View>,ALL_COST>(elements, weights, glb);
00289
00290 int delta = std::min(x.unknownSize(), x.cardMax() - x.glbSize());
00291
00292 for (int i=0; i<delta-1; i++) {
00293 if (currentWeights[i] >= 0)
00294 break;
00295 lowCost+=currentWeights[i];
00296 }
00297 lowestCost = lowCost;
00298 if (delta>0 && currentWeights[delta-1]<0)
00299 lowestCost+=currentWeights[delta-1];
00300
00301 for (int i=0; i<delta; i++) {
00302 if (currentWeights[size-i-1]<=0)
00303 break;
00304 highestCost += currentWeights[size-i-1];
00305 }
00306
00307 }
00308
00309 GECODE_ME_CHECK(y.gq(home, lowestCost));
00310 GECODE_ME_CHECK(y.lq(home, highestCost));
00311
00312 ModEvent me;
00313 {
00314 UnknownRanges<View> ur2(x);
00315 Iter::Ranges::ToValues<UnknownRanges<View> > urv(ur2);
00316 OverweightValues<Iter::Ranges::ToValues<UnknownRanges<View> > >
00317 ov(y.max()-lowCost, elements, weights, urv);
00318 Iter::Values::ToRanges<OverweightValues<
00319 Iter::Ranges::ToValues<UnknownRanges<View> > > > ovr(ov);
00320 me = x.excludeI(home, ovr);
00321 GECODE_ME_CHECK(me);
00322 }
00323
00324 if (x.assigned()) {
00325 GlbRanges<View> glb(x);
00326 int w =
00327 weightI<GlbRanges<View>,ALL_COST>(elements, weights, glb);
00328 GECODE_ME_CHECK(y.eq(home, w));
00329 return ES_SUBSUMED(this,home);
00330 }
00331 return me_modified(me) ? ES_NOFIX : ES_FIX;
00332 }
00333
00334 template <class View>
00335 Support::Symbol
00336 Weights<View>::ati(void) {
00337 return Reflection::mangle<View>("Gecode::Set::Int::Weights");
00338 }
00339
00340 template <class View>
00341 Reflection::ActorSpec
00342 Weights<View>::spec(const Space* home, Reflection::VarMap& m) const {
00343 Reflection::ActorSpec s(ati());
00344 return s << Reflection::Arg::newIntArray(elements)
00345 << Reflection::Arg::newIntArray(weights)
00346 << x.spec(home, m)
00347 << y.spec(home, m);
00348 }
00349
00350 template <class View>
00351 void
00352 Weights<View>::post(Space* home, Reflection::VarMap& vars,
00353 const Reflection::ActorSpec& spec) {
00354 spec.checkArity(4);
00355 Reflection::IntArrayArg* elementsArg = spec[0]->toIntArray();
00356 Reflection::IntArrayArg* weightsArg = spec[1]->toIntArray();
00357 IntArgs elements(elementsArg->size());
00358 IntArgs weights(weightsArg->size());
00359 for (int i=elementsArg->size(); i--;)
00360 elements[i] = (*elementsArg)[i];
00361 for (int i=weightsArg->size(); i--;)
00362 weights[i] = (*weightsArg)[i];
00363 View x0(home, vars, spec[2]);
00364 Gecode::Int::IntView x1(home, vars, spec[3]);
00365 (void) new (home) Weights<View>(home,elements,weights,x0,x1);
00366 }
00367
00368 }}}
00369
00370