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 #include "gecode/set.hh"
00029 #include "gecode/int.hh"
00030
00031 namespace Gecode { namespace Set { namespace Int {
00032
00034 template <class I>
00035 class OverweightValues {
00036 private:
00038 int threshold;
00040 I iter;
00042 const Support::SharedArray<int> elements;
00044 const Support::SharedArray<int> weights;
00046 int index;
00048 void next(void);
00049 public:
00051
00052
00053 OverweightValues(void);
00055 OverweightValues(int t,
00056 Support::SharedArray<int>& elements0,
00057 Support::SharedArray<int>& weights0,
00058 I& i);
00060 void init(int t,
00061 Support::SharedArray<int>& elements0,
00062 Support::SharedArray<int>& weights0,
00063 I& i);
00065
00067
00068
00069 bool operator()(void) const;
00071 void operator++(void);
00073
00074
00075
00076 int val(void) const;
00078 };
00079
00080 template <class I>
00081 forceinline void
00082 OverweightValues<I>::next(void) {
00083 while (iter()) {
00084 while (elements[index]<iter.val()) index++;
00085 assert(elements[index]==iter.val());
00086 if (weights[index] > threshold) {
00087 return;
00088 }
00089 ++iter;
00090 }
00091 }
00092
00093 template <class I>
00094 forceinline
00095 OverweightValues<I>::OverweightValues(void) {}
00096
00097 template <class I>
00098 forceinline
00099 OverweightValues<I>::OverweightValues(int t,
00100 Support::SharedArray<int>& elements0,
00101 Support::SharedArray<int>& weights0,
00102 I& i) : threshold(t),
00103 iter(i),
00104 elements(elements0),
00105 weights(weights0),
00106 index(0) {
00107 next();
00108 }
00109
00110 template <class I>
00111 forceinline void
00112 OverweightValues<I>::init(int t,
00113 Support::SharedArray<int>& elements0,
00114 Support::SharedArray<int>& weights0,
00115 I& i) {
00116 threshold = t; iter = i;
00117 elements = elements0; weights = weights0;
00118 index = 0;
00119 next();
00120 }
00121
00122 template <class I>
00123 forceinline bool
00124 OverweightValues<I>::operator()(void) const { return iter(); }
00125
00126 template <class I>
00127 forceinline void
00128 OverweightValues<I>::operator++(void) { ++iter; next(); }
00129
00130 template <class I>
00131 forceinline int
00132 OverweightValues<I>::val(void) const { return elements[index]; }
00133
00134 forceinline
00135 Weights::Weights(Space* home,
00136 const IntArgs& elements0, const IntArgs& weights0,
00137 SetView x0, Gecode::Int::IntView y0)
00138 : Propagator(home), elements(elements0.size()), weights(weights0.size()),
00139 x(x0), y(y0) {
00140 x.subscribe(home,this, PC_SET_ANY);
00141 y.subscribe(home,this, Gecode::Int::PC_INT_BND);
00142 for (int i=elements0.size(); i--;) {
00143 elements[i] = elements0[i];
00144 weights[i] = weights0[i];
00145 }
00146 }
00147
00148 forceinline
00149 Weights::Weights(Space* home, bool share, Weights& p)
00150 : Propagator(home,share,p) {
00151 x.update(home,share,p.x);
00152 y.update(home,share,p.y);
00153 elements.update(share,p.elements);
00154 weights.update(share,p.weights);
00155 }
00156
00157 inline ExecStatus
00158 Weights::post(Space* home, const IntArgs& elements, const IntArgs& weights,
00159 SetView x, Gecode::Int::IntView y) {
00160 if (elements.size() != weights.size())
00161 throw ArgumentSizeMismatch("Weights");
00162 GECODE_AUTOARRAY(int, els_arr, elements.size());
00163 for (int i=elements.size(); i--;)
00164 els_arr[i] = elements[i];
00165 IntSet els(els_arr, elements.size());
00166 IntSetRanges er(els);
00167 GECODE_ME_CHECK(x.intersectI(home, er));
00168 (void) new (home) Weights(home,elements,weights,x,y);
00169 return ES_OK;
00170 }
00171
00172 }}}
00173
00174