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 namespace Gecode { namespace Int { namespace GCC {
00039
00040
00041 template <class View, class Card, bool isView, bool shared>
00042 inline
00043 BndImp<View, Card, isView, shared>::
00044 BndImp(Space* home, ViewArray<View>& x0, ViewArray<Card>& k0,
00045 bool cf, bool nolbc) :
00046 Propagator(home), x(x0), k(k0), lps(NULL), ups(NULL),
00047 card_fixed(cf), skip_lbc(nolbc) {
00048 force(home);
00049 x.subscribe(home, this, PC_INT_BND);
00050 k.subscribe(home, this, PC_INT_BND);
00051 }
00052
00053
00054 template <class View, class Card, bool isView, bool shared>
00055 forceinline
00056 BndImp<View, Card, isView, shared>::
00057 BndImp(Space* home, bool share, BndImp<View, Card, isView, shared>& p)
00058 : Propagator(home, share, p), lps(NULL), ups(NULL),
00059 card_fixed(p.card_fixed), skip_lbc(p.skip_lbc) {
00060 x.update(home, share, p.x);
00061 k.update(home, share, p.k);
00062 }
00063
00064 template <class View, class Card, bool isView, bool shared>
00065 size_t
00066 BndImp<View, Card, isView, shared>::dispose(Space* home){
00067 unforce(home);
00068 if (!home->failed()) {
00069 x.cancel(home,this, PC_INT_BND);
00070 k.cancel(home,this, PC_INT_BND);
00071 }
00072 if (lps != NULL) {
00073 delete lps;
00074 }
00075 if (ups != NULL) {
00076 delete ups;
00077 }
00078 (void) Propagator::dispose(home);
00079 return sizeof(*this);
00080 }
00081
00082 template <class View, class Card, bool isView, bool shared>
00083 size_t
00084 BndImp<View, Card, isView, shared>::allocated(void) const {
00085 size_t s = 0;
00086 if (lps != NULL)
00087 s += lps->allocated();
00088 if (ups != NULL)
00089 s += ups->allocated();
00090 return s;
00091 }
00092
00093 template <class View, class Card, bool isView, bool shared>
00094 Actor*
00095 BndImp<View, Card, isView, shared>::copy(Space* home, bool share){
00096 return new (home) BndImp<View, Card, isView, shared>
00097 (home, share, *this);
00098 }
00099
00100 template <class View, class Card, bool isView, bool shared>
00101 PropCost
00102 BndImp<View, Card, isView, shared>::cost(ModEventDelta) const {
00103
00104
00105
00106
00107
00108
00109
00110 return cost_hi(x.size(),PC_LINEAR_HI);
00111 }
00112
00113 template <class View, class Card, bool isView, bool shared>
00114 Support::Symbol
00115 BndImp<View, Card, isView, shared>::ati(void) {
00116 Support::Symbol mangled("Gecode::Int::GCC::Bnd");
00117 mangled += "<";
00118 mangled += View::type();
00119 mangled += ",";
00120 mangled += Card::type();
00121 mangled += ",";
00122 mangled += (isView ? "true" : "false");
00123 mangled += ",";
00124 mangled += (shared ? "true" : "false");
00125 mangled += ">";
00126 return mangled;
00127 }
00128
00129 template <class View, class Card, bool isView, bool shared>
00130 Reflection::ActorSpec
00131 BndImp<View,Card,isView,shared>::spec(const Space* home,
00132 Reflection::VarMap& m) const {
00133 Reflection::ActorSpec s(ati());
00134 return s << x.spec(home, m) << k.spec(home, m) << card_fixed << skip_lbc;
00135 }
00136
00137 template <class View, class Card, bool isView, bool shared>
00138 void
00139 BndImp<View,Card,isView,shared>::post(Space* home, Reflection::VarMap& vars,
00140 const Reflection::ActorSpec& spec) {
00141 spec.checkArity(4);
00142 ViewArray<View> x(home, vars, spec[0]);
00143 ViewArray<Card> k(home, vars, spec[1]);
00144 bool card_fixed = spec[2]->toInt();
00145 bool skip_lbc = spec[3]->toInt();
00146 (void) new (home) BndImp(home, x, k, card_fixed, skip_lbc);
00147 }
00148
00149 template <class View, class Card, bool isView, bool shared>
00150 ExecStatus
00151 BndImp<View, Card, isView, shared>::propagate(Space* home, ModEventDelta) {
00152 bool all_assigned = true;
00153 bool mod = false;
00154 int smin = 0;
00155 int smax = 0;
00156
00157 if (isView) {
00158
00159
00160
00161
00162 int m = k.size();
00163 bool locut = k[0].max() == 0;
00164 bool hicut = k[m - 1].max() == 0;
00165
00166 if (locut) {
00167 int low = k[0].card();
00168 for (int i = 0; i < x.size(); i++) {
00169 ModEvent me = x[i].gr(home, low);
00170 GECODE_ME_CHECK(me);
00171 mod |= me_modified(me) && (x[i].min() != low + 1);
00172 mod |= shared && me_modified(me);
00173 }
00174 }
00175 if (hicut) {
00176 int hi = k[m - 1].card();
00177 for (int i = 0; i < x.size(); i++) {
00178 ModEvent me = x[i].le(home, hi);
00179 GECODE_ME_CHECK(me);
00180 mod |= me_modified(me) && (x[i].max() != hi - 1);
00181 mod |= shared && me_modified(me);
00182 }
00183 }
00184
00185 if (locut || hicut) {
00186 int cmin = k[0].card();
00187 int cmax = k[m - 1].card();
00188 if (k[0].max() == 0) {
00189 cmin = k[1].card();
00190 }
00191 if (k[m - 1].max() == 0) {
00192 cmax = k[m - 2].card();
00193 }
00194 reduce_card<Card>(cmin, cmax, k);
00195
00196 if (lps != NULL) {
00197 delete lps; lps = NULL;
00198 assert(ups != NULL);
00199 delete ups; ups = NULL;
00200 }
00201 }
00202 }
00203
00204 GECODE_AUTOARRAY(int, count, k.size());
00205 for (int i = k.size(); i--; ) {
00206 count[i] = 0;
00207 }
00208
00209 int noa = 0;
00210 int single = 0;
00211 int xlb = 0;
00212 int xub = 0;
00213 for (int i = x.size(); i--; ) {
00214 bool b = x[i].assigned();
00215 xlb += x[i].min();
00216 xub += x[i].max();
00217 all_assigned &= b;
00218 if (b) {
00219 noa++;
00220 int idx = lookupValue(k,x[i].val());
00221
00222
00223 if (idx == -1)
00224 return ES_FAILED;
00225 count[idx]++;
00226 } else {
00227 single = i;
00228 }
00229 }
00230
00231 if (isView) {
00232
00233 if (noa > 0) {
00234 int n = x.size();
00235 int ks = k.size();
00236
00237 for (int i = ks; i--; ) {
00238 if (!k[i].assigned()) {
00239 int ub = n - (noa - count[i]);
00240 int lb = count[i];
00241 ModEvent melq = k[i].lq(home, ub);
00242 GECODE_ME_CHECK(melq);
00243 mod |= me_modified(melq) && (k[i].max() != ub);
00244 mod |= shared && me_modified(melq);
00245
00246 ModEvent megq = k[i].gq(home, lb);
00247 GECODE_ME_CHECK(megq);
00248 mod |= me_modified(megq) && (k[i].min() != lb);
00249 mod |= shared && me_modified(megq);
00250 }
00251 }
00252 }
00253
00254 if (!card_consistent<View, Card>(smin, smax, x, k))
00255 return ES_FAILED;
00256
00257
00258 GECODE_ES_CHECK((prop_card<View, Card, shared>(home, x, k, mod)));
00259
00260
00261 int smax = 0;
00262 int smin = 0;
00263 int total_min = 0;
00264 int total_max = 0;
00265 for (int i = k.size(); i--; ) {
00266 smax += k[i].max();
00267 total_min += k[i].card() * k[i].min();
00268 total_max += k[i].card() * k[i].max();
00269 }
00270 int xsmax = x.size() - smax;
00271 int xsmin = x.size() - smin;
00272 smax = 0;
00273 smin = 0;
00274 bool card_ass = true;
00275 for (int i = k.size(); i--; ) {
00276 int lb = xsmax + k[i].max();
00277 int ub = xsmin + k[i].min();
00278 ModEvent me = k[i].gq(home, lb);
00279 GECODE_ME_CHECK(me);
00280 mod |= me_modified(me) && (k[i].min() != lb);
00281 mod |= shared && me_modified(me);
00282 smax += k[i].max();
00283
00284 me = k[i].lq(home, ub);
00285 GECODE_ME_CHECK(me);
00286 mod |= me_modified(me) && (k[i].max() != ub);
00287 mod |= shared && me_modified(me);
00288 card_ass &= k[i].assigned();
00289 }
00290 if (card_ass) {
00291 if (smax < x.size() || smax > x.size())
00292 return ES_FAILED;
00293
00294
00295 for (int i = x.size(); i--; ) {
00296 if (!x[i].assigned()) {
00297 int xmin = xub - x[i].max();
00298 int xgq = total_max - xmin;
00299
00300 int xmax = xlb - x[i].min();
00301 int xlq = total_max - xmax;
00302
00303 ModEvent me = x[i].gq(home, xgq);
00304 GECODE_ME_CHECK(me);
00305 mod |= me_modified(me) && (x[i].min() != xgq);
00306 mod |= shared && me_modified(me);
00307
00308 me = x[i].lq(home, xlq);
00309 GECODE_ME_CHECK(me);
00310 mod |= me_modified(me) && (x[i].max() != xlq);
00311 mod |= shared && me_modified(me);
00312 }
00313 }
00314 }
00315 }
00316
00317 for (int i = k.size(); i--; ) {
00318 count[i] = 0;
00319 }
00320
00321 all_assigned = true;
00322 noa = 0;
00323 single = 0;
00324
00325 for (int i = x.size(); i--; ) {
00326 bool b = x[i].assigned();
00327 xlb += x[i].min();
00328 xub += x[i].max();
00329 all_assigned &= b;
00330 if (b) {
00331 noa++;
00332 int idx = lookupValue(k,x[i].val());
00333
00334
00335 if (idx == -1)
00336 return ES_FAILED;
00337 count[idx]++;
00338 } else {
00339 single = i;
00340 }
00341 }
00342
00343 if (all_assigned) {
00344 for (int i = k.size(); i--; ) {
00345 int ci = count[i];
00346 if (! (k[i].min() <= ci && ci <= k[i].max())) {
00347 return ES_FAILED;
00348 } else {
00349 if (isView) {
00350 if (!k[i].assigned()) {
00351 ModEvent me = k[i].eq(home, ci);
00352 GECODE_ME_CHECK(me);
00353 mod |= k[i].assigned();
00354 }
00355 all_assigned &= k[i].assigned();
00356 }
00357 }
00358 }
00359 if (all_assigned)
00360 return ES_SUBSUMED(this,home);
00361 }
00362
00363 if (isView) {
00364
00365 int m = k.size();
00366 bool locut = k[0].max() == 0;
00367 bool hicut = k[m - 1].max() == 0;
00368
00369 if (locut) {
00370 int low = k[0].card();
00371 for (int i = 0; i < x.size(); i++) {
00372 ModEvent me = x[i].gr(home, low);
00373 GECODE_ME_CHECK(me);
00374 mod |= me_modified(me) && (x[i].min() != low + 1);
00375 mod |= shared && me_modified(me);
00376 }
00377 }
00378 if (hicut) {
00379 int hi = k[m - 1].card();
00380 for (int i = 0; i < x.size(); i++) {
00381 ModEvent me = x[i].le(home, hi);
00382 GECODE_ME_CHECK(me);
00383 mod |= me_modified(me) && (x[i].max() != hi - 1);
00384 mod |= shared && me_modified(me);
00385 }
00386 }
00387
00388 if (locut || hicut) {
00389 int cmin = k[0].card();
00390 int cmax = k[m - 1].card();
00391 if (k[0].max() == 0) {
00392 cmin = k[1].card();
00393 }
00394 if (k[m - 1].max() == 0) {
00395 cmax = k[m - 2].card();
00396 }
00397 reduce_card<Card>(cmin, cmax, k);
00398
00399 if (lps != NULL) {
00400 delete lps;
00401 lps = NULL;
00402 assert(ups != NULL);
00403 delete ups;
00404 ups = NULL;
00405 }
00406 }
00407 }
00408
00409 ExecStatus es_ubc = ES_FIX;
00410 ExecStatus es_lbc = ES_FIX;
00411 int n = x.size();
00412
00413 GECODE_AUTOARRAY(int, mu, n);
00414 GECODE_AUTOARRAY(int, nu, n);
00415
00416 for (int i = n; i--; ) {
00417 nu[i] = i;
00418 mu[i] = i;
00419 }
00420
00421 MaxInc<View> max_inc(x);
00422 Support::quicksort<int, MaxInc<View> >(mu, n, max_inc);
00423
00424
00425 MinInc<View> min_inc(x);
00426 Support::quicksort<int, MinInc<View> >(nu, n, min_inc);
00427
00428 if (isView) {
00429
00430 assert(k[0].card() == x[nu[0]].min());
00431 }
00432
00433
00434 int cur_minx = x[nu[0]].min();
00435 if (lps == NULL) {
00436 assert (ups == NULL);
00437 lps = new PartialSum<Card>(cur_minx, k.size(), k, false);
00438 ups = new PartialSum<Card>(cur_minx, k.size(), k, true);
00439 }
00440
00441 if (isView) {
00442
00443
00444 if (lps->check_update_min(k)) {
00445 delete lps;
00446 lps = new PartialSum<Card>(cur_minx, k.size(), k, false);
00447 }
00448
00449 if (ups->check_update_max(k)) {
00450 delete ups;
00451 ups = new PartialSum<Card>(cur_minx, k.size(), k, true);
00452 }
00453 }
00454
00455
00456 assert(lps->minValue() == ups->minValue());
00457 assert(lps->maxValue() == ups->maxValue());
00458
00459 bool minima_equal = lps->minValue() == ups->minValue();
00460 bool maxima_equal = lps->maxValue() == ups->maxValue();
00461
00462 if (!minima_equal || !maxima_equal ) {
00463 delete lps;
00464 lps = new PartialSum<Card>(cur_minx, k.size(), k, false);
00465 delete ups;
00466 ups = new PartialSum<Card>(cur_minx, k.size(), k, true);
00467 }
00468
00469
00470
00471 assert(lps->minValue() <= x[nu[0]].min());
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485 GECODE_AUTOARRAY(HallInfo, hall, (2 * n + 2));
00486 GECODE_AUTOARRAY(Rank, rank, n);
00487
00488 int nb = 0;
00489
00490 int min = x[nu[0]].min();
00491 int max = x[mu[0]].max() + 1;
00492 int last = lps->firstValue + 1;
00493 hall[0].bounds = last;
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503 {
00504 int i = 0;
00505 int j = 0;
00506 while (true) {
00507 if (i < n && min < max) {
00508 if (min != last) {
00509 last = min;
00510 hall[++nb].bounds = last;
00511 }
00512 rank[nu[i]].min = nb;
00513 if (++i < n) {
00514 min = x[nu[i]].min();
00515 }
00516 } else {
00517 if (max != last) {
00518 last = max;
00519 hall[++nb].bounds = last;
00520 }
00521 rank[mu[j]].max = nb;
00522 if (++j == n) {
00523 break;
00524 }
00525 max = x[mu[j]].max() + 1;
00526 }
00527 }
00528 }
00529
00530 int rightmost = nb + 1;
00531 hall[rightmost].bounds = ups->lastValue + 1 ;
00532
00533 skip_lbc = true;
00534 for (int i = k.size(); i--; ) {
00535 skip_lbc &= (k[i].min() == 0);
00536 }
00537
00538 if (!card_fixed && !skip_lbc) {
00539 es_lbc = lbc<View, Card, shared>(home, x, nb, hall, rank,lps, mu, nu);
00540 GECODE_ES_CHECK(es_lbc);
00541 mod |= (es_lbc == ES_NOFIX);
00542 }
00543
00544 es_ubc = ubc<View, Card, shared>(home, x, nb, hall, rank, ups, mu, nu);
00545 GECODE_ES_CHECK(es_ubc);
00546 mod |= (es_ubc == ES_NOFIX);
00547
00548 if (isView) {
00549 GECODE_ES_CHECK((prop_card<View, Card, shared>(home, x, k, mod)));
00550 }
00551
00552 all_assigned = true;
00553 noa = 0;
00554 single = 0;
00555 for (int i = k.size(); i--; ) {
00556 count[i] = 0;
00557 }
00558
00559 for (int i = x.size(); i--; ) {
00560 bool b = x[i].assigned();
00561 all_assigned &= b;
00562 if (b) {
00563 noa++;
00564 int idx = lookupValue(k,x[i].val());
00565 count[idx]++;
00566 } else {
00567 single = i;
00568 }
00569 }
00570
00571 if (all_assigned) {
00572 for (int i = k.size(); i--; ) {
00573 int ci = count[i];
00574 if (! (k[i].min() <= ci && ci <= k[i].max())) {
00575 return ES_FAILED;
00576 } else {
00577 if (isView) {
00578 if (!k[i].assigned()) {
00579 ModEvent me = k[i].eq(home, ci);
00580 GECODE_ME_CHECK(me);
00581 mod |= k[i].assigned();
00582 }
00583 all_assigned &= k[i].assigned();
00584 }
00585 }
00586 }
00587 if (all_assigned)
00588 return ES_SUBSUMED(this,home);
00589 }
00590
00591 return mod ? ES_NOFIX : ES_FIX;
00592 }
00593
00602 template <class View1, class View2>
00603 class SharingTest {
00604 public:
00609 static bool shared(Space* home, ViewArray<View1>& x0,
00610 ViewArray<View2>& k0) {
00611 ViewArray<View1> xc(home, x0.size()+k0.size());
00612 for (int i = 0; i < x0.size(); i++) {
00613 xc[i] = x0[i];
00614 }
00615 for (int i = x0.size(); i < x0.size()+k0.size(); i++) {
00616 xc[i] = k0[i - x0.size()].intview();
00617 }
00618 return xc.shared();
00619 }
00620 };
00621
00626 template <>
00627 class SharingTest<IntView,OccurBndsView> {
00628 public:
00630 static bool shared(Space*,
00631 ViewArray<IntView>& xs, ViewArray<OccurBndsView>&) {
00632 return xs.shared();
00633 }
00634 };
00635
00636 template <class View, class Card, bool isView>
00637 ExecStatus
00638 Bnd<View, Card, isView>::post(Space* home,
00639 ViewArray<View>& x0,
00640 ViewArray<Card>& k0) {
00641 bool cardfix = true;
00642 bool nolbc = true;
00643 for (int i = k0.size(); i--; ) {
00644 cardfix &= k0[i].assigned();
00645 nolbc &= (k0[i].min() == 0);
00646 }
00647 if (SharingTest<View,Card>::shared(home,x0,k0)) {
00648 new (home) BndImp<View, Card, isView, true>
00649 (home, x0, k0, cardfix, nolbc);
00650 } else {
00651 new (home) BndImp<View, Card, isView, false>
00652 (home, x0, k0, cardfix, nolbc);
00653 }
00654 return ES_OK;
00655 }
00656
00657 }}}
00658
00659
00660