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

weights.cc

Go to the documentation of this file.
00001 /*
00002  *  Main authors:
00003  *     Guido Tack <tack@gecode.org>
00004  *     Christian Schulte <schulte@gecode.org>
00005  *
00006  *  Contributing authors:
00007  *     Gabor Szokoli <szokoli@gecode.org>
00008  *
00009  *  Copyright:
00010  *     Guido Tack, 2004
00011  *     Christian Schulte, 2004
00012  *     Gabor Szokoli, 2004
00013  *
00014  *  Last modified:
00015  *     $Date: 2006-07-19 14:57:38 +0200 (Wed, 19 Jul 2006) $ by $Author: schulte $
00016  *     $Revision: 3413 $
00017  *
00018  *  This file is part of Gecode, the generic constraint
00019  *  development environment:
00020  *     http://www.gecode.org
00021  *
00022  *  See the file "LICENSE" for information on usage and
00023  *  redistribution of this file, and for a
00024  *     DISCLAIMER OF ALL WARRANTIES.
00025  *
00026  */
00027 
00028 
00029 
00030 #include "gecode/set/int.hh"
00031 
00032 #include "gecode/iter.hh"
00033 
00034 using namespace Gecode::Int;
00035 
00036 namespace Gecode { namespace Set { namespace Int {
00037 
00038   PropCost
00039   Weights::cost(void) const {
00040     return PC_LINEAR_LO;
00041   }
00042 
00043   size_t
00044   Weights::dispose(Space* home) {
00045     assert(!home->failed());
00046     x.cancel(home,this, PC_SET_ANY);
00047     y.cancel(home,this, Gecode::Int::PC_INT_BND);
00048     (void) Propagator::dispose(home);
00049     return sizeof(*this);
00050   }
00051 
00052   Actor*
00053   Weights::copy(Space* home, bool share) {
00054     return new (home) Weights(home,share,*this);
00055   }
00056 
00057   enum CostType { POS_COST, NEG_COST, ALL_COST };
00058 
00059   template <class I, CostType c>
00060   forceinline
00061   int weightI(Support::SharedArray<int>& elements,
00062               Support::SharedArray<int>& weights,
00063               I& iter) {
00064     int sum = 0;
00065     int i = 0;
00066     for (Iter::Ranges::ToValues<I> v(iter); v(); ++v) {
00067       // Skip all elements below the current
00068       while (elements[i]<v.val()) i++;
00069       assert(elements[i] == v.val());
00070       switch (c) {
00071       case ALL_COST:
00072         sum += weights[i];
00073         break;
00074       case POS_COST:
00075         if (weights[i] > 0) sum += weights[i];
00076         break;
00077       case NEG_COST:
00078         if (weights[i] < 0) sum += weights[i];
00079         break;
00080       default: GECODE_NEVER;
00081       }
00082     }
00083     return sum;
00084   }
00085 
00086 
00088   class IntLt {
00089   public:
00090     bool operator()(int x, int y);
00091   };
00092 
00093   forceinline bool 
00094   IntLt::operator()(int x, int y) {
00095     return x < y;
00096   }
00097 
00098   ExecStatus
00099   Weights::propagate(Space* home) {
00100 
00101     if (x.assigned()) {
00102       GlbRanges<SetView> glb(x);
00103       int w = 
00104         weightI<GlbRanges<SetView>,ALL_COST>(elements, weights, glb);
00105       GECODE_ME_CHECK(y.eq(home, w));
00106       return ES_SUBSUMED;
00107     }
00108 
00109     int lowCost;
00110     int lowestCost;
00111     int highestCost;
00112     int size = elements.size();
00113     {
00114       UnknownRanges<SetView> ur(x);
00115       Iter::Ranges::ToValues<UnknownRanges<SetView> > urv(ur);
00116       GECODE_AUTOARRAY(int, currentWeights, size);
00117       for (int i=0; i<size; i++) {
00118         if (!urv() || elements[i]<urv.val()) {
00119           currentWeights[i] = 0;
00120         } else {
00121           assert(elements[i] == urv.val());
00122           currentWeights[i] = weights[i];
00123           ++urv;
00124         }
00125       }
00126 
00127       IntLt ilt;
00128       Support::quicksort<int>(currentWeights, size, ilt);
00129 
00130       GlbRanges<SetView> glb(x);
00131       lowCost = weightI<GlbRanges<SetView>,ALL_COST>(elements, weights, glb);
00132       highestCost =
00133         weightI<GlbRanges<SetView>,ALL_COST>(elements, weights, glb);
00134 
00135       int delta = std::min(x.unknownSize(), x.cardMax() - x.glbSize());
00136 
00137       for (int i=0; i<delta-1; i++) {
00138         if (currentWeights[i] >= 0)
00139           break;
00140         lowCost+=currentWeights[i];
00141       }
00142       lowestCost = lowCost;
00143       if (delta>0 && currentWeights[delta-1]<0)
00144         lowestCost+=currentWeights[delta-1];
00145 
00146       for (int i=0; i<delta; i++) {
00147         if (currentWeights[size-i-1]<=0)
00148           break;
00149         highestCost += currentWeights[size-i-1];
00150       }
00151 
00152     }
00153 
00154     GECODE_ME_CHECK(y.gq(home, lowestCost));
00155     GECODE_ME_CHECK(y.lq(home, highestCost));
00156 
00157     ModEvent me;
00158     {
00159       UnknownRanges<SetView> ur2(x);
00160       Iter::Ranges::ToValues<UnknownRanges<SetView> > urv(ur2);
00161       OverweightValues<Iter::Ranges::ToValues<UnknownRanges<SetView> > >
00162         ov(y.max()-lowCost, elements, weights, urv);
00163       Iter::Values::ToRanges<OverweightValues<
00164         Iter::Ranges::ToValues<UnknownRanges<SetView> > > > ovr(ov);
00165       me = x.excludeI(home, ovr);
00166       GECODE_ME_CHECK(me);
00167     }
00168 
00169     if (x.assigned()) {
00170       GlbRanges<SetView> glb(x);
00171       int w = 
00172         weightI<GlbRanges<SetView>,ALL_COST>(elements, weights, glb);
00173       GECODE_ME_CHECK(y.eq(home, w));
00174       return ES_SUBSUMED;
00175     }
00176     return me_modified(me) ? ES_NOFIX : ES_FIX;
00177   }
00178 
00179 
00180 }}}
00181 
00182 // STATISTICS: set-prop