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 namespace Gecode { namespace Int { namespace GCC {
00038
00039 template <class View, class Card, bool isView>
00040 inline
00041 Val<View, Card, isView>::Val(Space& home, ViewArray<View>& x0,
00042 ViewArray<Card>& k0)
00043 : Propagator(home), x(x0), k(k0){
00044 home.notice(*this,AP_DISPOSE);
00045 x.subscribe(home, *this, PC_INT_VAL);
00046 k.subscribe(home, *this, PC_INT_VAL);
00047 }
00048
00049 template <class View, class Card, bool isView>
00050 forceinline
00051 Val<View, Card, isView>::Val(Space& home, bool share,
00052 Val<View, Card, isView>& p)
00053 : Propagator(home,share,p) {
00054 x.update(home,share, p.x);
00055 k.update(home,share, p.k);
00056 }
00057
00058 template <class View, class Card, bool isView>
00059 size_t
00060 Val<View, Card, isView>::dispose(Space& home) {
00061 home.ignore(*this,AP_DISPOSE);
00062 x.cancel(home,*this, PC_INT_VAL);
00063 k.cancel(home,*this, PC_INT_VAL);
00064 (void) Propagator::dispose(home);
00065 return sizeof(*this);
00066 }
00067
00068 template <class View, class Card, bool isView>
00069 Actor*
00070 Val<View, Card, isView>::copy(Space& home, bool share) {
00071 return new (home) Val<View, Card, isView>(home,share,*this);
00072 }
00073
00074 template <class View, class Card, bool isView>
00075 ExecStatus
00076 Val<View, Card, isView>::post(Space& home,
00077 ViewArray<View>& x0,
00078 ViewArray<Card>& k0) {
00079 new (home) Val<View, Card, isView>(home, x0, k0);
00080 return ES_OK;
00081 }
00082
00088 template <class View, class Card, bool isView>
00089 PropCost
00090 Val<View, Card, isView>::cost(const Space&, const ModEventDelta&) const {
00091 return PropCost::linear(PropCost::HI,x.size());
00092 }
00093
00094 template <class View, class Card, bool isView>
00095 ExecStatus
00096 Val<View, Card, isView>::propagate(Space& home, const ModEventDelta&) {
00097 assert(x.size() > 0);
00098
00099 bool mod = false;
00100 int n = x.size();
00101 int m = k.size();
00102
00103 Region r(home);
00104
00105 int* count = r.alloc<int>(m);
00106
00107 int* rem = r.alloc<int>(m);
00108
00109 bool* onrem = r.alloc<bool>(m);
00110
00111 int rs = 0;
00112
00113
00114 int sum_min = 0;
00115 int removed = 0;
00116 for (int i = m; i--; ) {
00117
00118 removed += k[i].counter();
00119 sum_min += k[i].min();
00120
00121 count[i] = 0;
00122 onrem[i] = false;
00123 }
00124
00125 for (int i = m; i--; ) {
00126
00127
00128 if (!k[i].assigned()) {
00129 int mub = n + removed - (sum_min - k[i].min());
00130 ModEvent me = k[i].lq(home, mub);
00131 GECODE_ME_CHECK(me);
00132 mod |= (me_modified(me) && k[i].max() != mub);
00133 }
00134 }
00135
00136
00137 bool all_assigned = true;
00138
00139 int noa = 0;
00140
00141 int t_noa = 0;
00142 for (int i = n; i--; ) {
00143 bool b = x[i].assigned();
00144 all_assigned &= b;
00145 if (b) {
00146 int idx = lookupValue(k,x[i].val());
00147 if (idx == -1)
00148 return ES_FAILED;
00149 count[idx]++;
00150 noa++;
00151 }
00152 }
00153
00154
00155 int non = x.size() - noa;
00156
00157
00158 if (all_assigned) {
00159
00160 for (int i = m; i--; ) {
00161 int ci = count[i] + k[i].counter();
00162 if (!(k[i].min() <= ci && ci <= k[i].max())) {
00163 return ES_FAILED;
00164 }
00165
00166 if (isView) {
00167 if (!k[i].assigned()) {
00168 ModEvent me = k[i].eq(home, ci);
00169 GECODE_ME_CHECK(me);
00170 mod |= k[i].assigned();
00171 }
00172 }
00173 }
00174 return ES_SUBSUMED(*this,home);
00175 }
00176
00177
00178 int req = 0;
00179
00180
00181 int n_r = 0;
00182
00183
00184 int single = 0;
00185
00186 for (int i = m; i--; ) {
00187 int ci = count[i] + k[i].counter();
00188 t_noa += ci;
00189 if (ci == 0) {
00190 req += k[i].min();
00191 n_r++;
00192 single = i;
00193 }
00194
00195
00196
00197 if (req > non) {
00198 return ES_FAILED;
00199 }
00200 }
00201
00202
00203 if (req == non && n_r == 1) {
00204 for (int i = n; i--; ) {
00205
00206 if (!x[i].assigned()) {
00207 ModEvent me = x[i].eq(home, k[single].card());
00208 count[single]++;
00209 GECODE_ME_CHECK(me);
00210 }
00211 }
00212
00213 if (x.shared(home) && count[single] < k[single].min()) {
00214 count[single] = k[single].min();
00215 }
00216
00217 for (int i = m; i--; ) {
00218 int ci = count[i] + k[i].counter();
00219
00220 if (!(k[i].min() <= ci && ci <= k[i].max())) {
00221 return ES_FAILED;
00222 }
00223
00224 if (isView) {
00225 if (!k[i].assigned()) {
00226 ModEvent me = k[i].eq(home, ci);
00227 GECODE_ME_CHECK(me);
00228 }
00229 }
00230 }
00231 return ES_SUBSUMED(*this,home);
00232 }
00233
00234 for (int i = m; i--; ) {
00235 int ci = count[i] + k[i].counter();
00236 if (ci == k[i].max() && !onrem[i]) {
00237 rem[rs] = k[i].card();
00238 k[i].counter(ci);
00239 rs++;
00240 onrem[i] = true;
00241 if (isView) {
00242
00243 if (!k[i].assigned()) {
00244 ModEvent me = k[i].eq(home, ci);
00245 GECODE_ME_CHECK(me);
00246 mod |= k[i].assigned();
00247 }
00248 }
00249 } else {
00250 if (ci > k[i].max())
00251 return ES_FAILED;
00252
00253
00254 if (isView) {
00255 if (!k[i].assigned()) {
00256 if (ci > k[i].min()) {
00257 ModEvent me = k[i].gq(home, ci);
00258 GECODE_ME_CHECK(me);
00259 mod |= k[i].assigned();
00260 mod |= (me_modified(me) && k[i].min() != ci);
00261 }
00262 int occupied = t_noa - ci;
00263 int mub = x.size() + removed - occupied;
00264
00265 ModEvent me = k[i].lq(home, mub);
00266 GECODE_ME_CHECK(me);
00267 mod |= k[i].assigned();
00268 mod |= (me_failed(me) && k[i].max() != mub);
00269 }
00270 }
00271 }
00272
00273 count[i] = 0;
00274 }
00275
00276
00277 for (int i = n; i--; ) {
00278 bool b = x[i].assigned();
00279 if (b) {
00280 int idx = lookupValue(k,x[i].val());
00281 if (idx == -1)
00282 return ES_FAILED;
00283 if (onrem[idx]) {
00284 x[i] = x[--n];
00285 x.size(n);
00286 }
00287 }
00288 }
00289
00290
00291 if (rs > 0) {
00292 IntSet remset(&rem[0], rs);
00293 for (int i = x.size(); i--;) {
00294 IntSetRanges rr(remset);
00295 if (!x[i].assigned()) {
00296 ModEvent me = x[i].minus_r(home, rr);
00297 if (me_failed(me))
00298 return ES_FAILED;
00299 mod |= x[i].assigned();
00300 }
00301 }
00302 }
00303
00304 all_assigned = true;
00305
00306 for (int i = x.size(); i--; ) {
00307 bool b = x[i].assigned();
00308 all_assigned &= b;
00309 if (b) {
00310 int idx = lookupValue(k,x[i].val());
00311 if (idx == -1)
00312 return ES_FAILED;
00313 count[idx]++;
00314 }
00315 }
00316
00317 if (all_assigned) {
00318 for (int i = k.size(); i--; ) {
00319 int ci = count[i] + k[i].counter();
00320 if (!(k[i].min() <= ci && ci <= k[i].max())) {
00321 return ES_FAILED;
00322 }
00323
00324 if (isView) {
00325 if (!k[i].assigned()) {
00326 ModEvent me = k[i].eq(home, ci);
00327 GECODE_ME_CHECK(me);
00328 mod |= k[i].assigned();
00329 }
00330 }
00331 }
00332 return ES_SUBSUMED(*this,home);
00333 }
00334
00335 if (isView) {
00336
00337 int reqmin = 0;
00338 int allmax = 0;
00339 m = k.size();
00340 n = x.size();
00341 for (int i = m; i--; ) {
00342 int ci = k[i].counter();
00343 if (ci > k[i].max() ) {
00344 return ES_FAILED;
00345 } else {
00346 allmax += (k[i].max() - ci);
00347 if (ci < k[i].min()) {
00348 reqmin += (k[i].min() - ci);
00349 }
00350 }
00351 if (k[i].min() > n) {
00352 return ES_FAILED;
00353 }
00354 if (!k[i].assigned()) {
00355 ModEvent me = k[i].lq(home, n);
00356 if (me_failed(me)) {
00357 return ES_FAILED;
00358 }
00359 }
00360 }
00361
00362 if (n < reqmin) {
00363 return ES_FAILED;
00364 }
00365
00366 if (allmax < n) {
00367 return ES_FAILED;
00368 }
00369 }
00370
00371 return mod ? ES_NOFIX : ES_FIX;
00372 }
00373
00374 }}}
00375
00376
00377