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 home.notice(*this,AP_DISPOSE);
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 home.ignore(*this,AP_DISPOSE);
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(const Space&, const ModEventDelta&) const {
00103
00104
00105
00106
00107
00108
00109
00110 return PropCost::linear(PropCost::HI,x.size());
00111 }
00112
00113 template <class View, class Card, bool isView, bool shared>
00114 ExecStatus
00115 BndImp<View, Card, isView, shared>::propagate(Space& home, const ModEventDelta&) {
00116 bool all_assigned = true;
00117 bool mod = false;
00118 int smin = 0;
00119 int smax = 0;
00120
00121 if (isView) {
00122
00123
00124
00125
00126 int m = k.size();
00127 bool locut = k[0].max() == 0;
00128 bool hicut = k[m - 1].max() == 0;
00129
00130 if (locut) {
00131 int low = k[0].card();
00132 for (int i = 0; i < x.size(); i++) {
00133 ModEvent me = x[i].gr(home, low);
00134 GECODE_ME_CHECK(me);
00135 mod |= me_modified(me) && (x[i].min() != low + 1);
00136 mod |= shared && me_modified(me);
00137 }
00138 }
00139 if (hicut) {
00140 int hi = k[m - 1].card();
00141 for (int i = 0; i < x.size(); i++) {
00142 ModEvent me = x[i].le(home, hi);
00143 GECODE_ME_CHECK(me);
00144 mod |= me_modified(me) && (x[i].max() != hi - 1);
00145 mod |= shared && me_modified(me);
00146 }
00147 }
00148
00149 if (locut || hicut) {
00150 int cmin = k[0].card();
00151 int cmax = k[m - 1].card();
00152 if (k[0].max() == 0) {
00153 cmin = k[1].card();
00154 }
00155 if (k[m - 1].max() == 0) {
00156 cmax = k[m - 2].card();
00157 }
00158 reduce_card<Card>(home,cmin, cmax, k);
00159
00160 if (lps != NULL) {
00161 delete lps; lps = NULL;
00162 assert(ups != NULL);
00163 delete ups; ups = NULL;
00164 }
00165 }
00166 }
00167
00168 Region r(home);
00169 int* count = r.alloc<int>(k.size());
00170 for (int i = k.size(); i--; )
00171 count[i] = 0;
00172
00173 int noa = 0;
00174 int single = 0;
00175 int xlb = 0;
00176 int xub = 0;
00177 for (int i = x.size(); i--; ) {
00178 bool b = x[i].assigned();
00179 xlb += x[i].min();
00180 xub += x[i].max();
00181 all_assigned &= b;
00182 if (b) {
00183 noa++;
00184 int idx = lookupValue(k,x[i].val());
00185
00186
00187 if (idx == -1)
00188 return ES_FAILED;
00189 count[idx]++;
00190 } else {
00191 single = i;
00192 }
00193 }
00194
00195 if (isView) {
00196
00197 if (noa > 0) {
00198 int n = x.size();
00199 int ks = k.size();
00200
00201 for (int i = ks; i--; ) {
00202 if (!k[i].assigned()) {
00203 int ub = n - (noa - count[i]);
00204 int lb = count[i];
00205 ModEvent melq = k[i].lq(home, ub);
00206 GECODE_ME_CHECK(melq);
00207 mod |= me_modified(melq) && (k[i].max() != ub);
00208 mod |= shared && me_modified(melq);
00209
00210 ModEvent megq = k[i].gq(home, lb);
00211 GECODE_ME_CHECK(megq);
00212 mod |= me_modified(megq) && (k[i].min() != lb);
00213 mod |= shared && me_modified(megq);
00214 }
00215 }
00216 }
00217
00218 if (!card_consistent<View, Card>(smin, smax, x, k))
00219 return ES_FAILED;
00220
00221
00222 GECODE_ES_CHECK((prop_card<View, Card, shared>(home, x, k, mod)));
00223
00224
00225 int smax = 0;
00226 int smin = 0;
00227 int total_min = 0;
00228 int total_max = 0;
00229 for (int i = k.size(); i--; ) {
00230 smax += k[i].max();
00231 total_min += k[i].card() * k[i].min();
00232 total_max += k[i].card() * k[i].max();
00233 }
00234 int xsmax = x.size() - smax;
00235 int xsmin = x.size() - smin;
00236 smax = 0;
00237 smin = 0;
00238 bool card_ass = true;
00239 for (int i = k.size(); i--; ) {
00240 int lb = xsmax + k[i].max();
00241 int ub = xsmin + k[i].min();
00242 ModEvent me = k[i].gq(home, lb);
00243 GECODE_ME_CHECK(me);
00244 mod |= me_modified(me) && (k[i].min() != lb);
00245 mod |= shared && me_modified(me);
00246 smax += k[i].max();
00247
00248 me = k[i].lq(home, ub);
00249 GECODE_ME_CHECK(me);
00250 mod |= me_modified(me) && (k[i].max() != ub);
00251 mod |= shared && me_modified(me);
00252 card_ass &= k[i].assigned();
00253 }
00254 if (card_ass) {
00255 if (smax < x.size() || smax > x.size())
00256 return ES_FAILED;
00257
00258
00259 for (int i = x.size(); i--; ) {
00260 if (!x[i].assigned()) {
00261 int xmin = xub - x[i].max();
00262 int xgq = total_max - xmin;
00263
00264 int xmax = xlb - x[i].min();
00265 int xlq = total_max - xmax;
00266
00267 ModEvent me = x[i].gq(home, xgq);
00268 GECODE_ME_CHECK(me);
00269 mod |= me_modified(me) && (x[i].min() != xgq);
00270 mod |= shared && me_modified(me);
00271
00272 me = x[i].lq(home, xlq);
00273 GECODE_ME_CHECK(me);
00274 mod |= me_modified(me) && (x[i].max() != xlq);
00275 mod |= shared && me_modified(me);
00276 }
00277 }
00278 }
00279 }
00280
00281 for (int i = k.size(); i--; )
00282 count[i] = 0;
00283
00284 all_assigned = true;
00285 noa = 0;
00286 single = 0;
00287
00288 for (int i = x.size(); i--; ) {
00289 bool b = x[i].assigned();
00290 xlb += x[i].min();
00291 xub += x[i].max();
00292 all_assigned &= b;
00293 if (b) {
00294 noa++;
00295 int idx = lookupValue(k,x[i].val());
00296
00297
00298 if (idx == -1)
00299 return ES_FAILED;
00300 count[idx]++;
00301 } else {
00302 single = i;
00303 }
00304 }
00305
00306 if (all_assigned) {
00307 for (int i = k.size(); i--; ) {
00308 int ci = count[i];
00309 if (! (k[i].min() <= ci && ci <= k[i].max())) {
00310 return ES_FAILED;
00311 } else {
00312 if (isView) {
00313 if (!k[i].assigned()) {
00314 ModEvent me = k[i].eq(home, ci);
00315 GECODE_ME_CHECK(me);
00316 mod |= k[i].assigned();
00317 }
00318 all_assigned &= k[i].assigned();
00319 }
00320 }
00321 }
00322 if (all_assigned)
00323 return ES_SUBSUMED(*this,home);
00324 }
00325
00326 if (isView) {
00327
00328 int m = k.size();
00329 bool locut = k[0].max() == 0;
00330 bool hicut = k[m - 1].max() == 0;
00331
00332 if (locut) {
00333 int low = k[0].card();
00334 for (int i = 0; i < x.size(); i++) {
00335 ModEvent me = x[i].gr(home, low);
00336 GECODE_ME_CHECK(me);
00337 mod |= me_modified(me) && (x[i].min() != low + 1);
00338 mod |= shared && me_modified(me);
00339 }
00340 }
00341 if (hicut) {
00342 int hi = k[m - 1].card();
00343 for (int i = 0; i < x.size(); i++) {
00344 ModEvent me = x[i].le(home, hi);
00345 GECODE_ME_CHECK(me);
00346 mod |= me_modified(me) && (x[i].max() != hi - 1);
00347 mod |= shared && me_modified(me);
00348 }
00349 }
00350
00351 if (locut || hicut) {
00352 int cmin = k[0].card();
00353 int cmax = k[m - 1].card();
00354 if (k[0].max() == 0) {
00355 cmin = k[1].card();
00356 }
00357 if (k[m - 1].max() == 0) {
00358 cmax = k[m - 2].card();
00359 }
00360 reduce_card<Card>(home,cmin, cmax, k);
00361
00362 if (lps != NULL) {
00363 delete lps;
00364 lps = NULL;
00365 assert(ups != NULL);
00366 delete ups;
00367 ups = NULL;
00368 }
00369 }
00370 }
00371
00372 ExecStatus es_ubc = ES_FIX;
00373 ExecStatus es_lbc = ES_FIX;
00374 int n = x.size();
00375
00376 int* mu = r.alloc<int>(n);
00377 int* nu = r.alloc<int>(n);
00378
00379 for (int i = n; i--; )
00380 nu[i] = mu[i] = i;
00381
00382
00383 MaxInc<View> max_inc(x);
00384 Support::quicksort<int, MaxInc<View> >(mu, n, max_inc);
00385
00386
00387 MinInc<View> min_inc(x);
00388 Support::quicksort<int, MinInc<View> >(nu, n, min_inc);
00389
00390 if (isView) {
00391
00392 assert(k[0].card() == x[nu[0]].min());
00393 }
00394
00395
00396 int cur_minx = x[nu[0]].min();
00397 if (lps == NULL) {
00398 assert (ups == NULL);
00399 lps = new PartialSum<Card>(cur_minx, k.size(), k, false);
00400 ups = new PartialSum<Card>(cur_minx, k.size(), k, true);
00401 }
00402
00403 if (isView) {
00404
00405
00406 if (lps->check_update_min(k)) {
00407 delete lps;
00408 lps = new PartialSum<Card>(cur_minx, k.size(), k, false);
00409 }
00410
00411 if (ups->check_update_max(k)) {
00412 delete ups;
00413 ups = new PartialSum<Card>(cur_minx, k.size(), k, true);
00414 }
00415 }
00416
00417
00418 assert(lps->minValue() == ups->minValue());
00419 assert(lps->maxValue() == ups->maxValue());
00420
00421 bool minima_equal = lps->minValue() == ups->minValue();
00422 bool maxima_equal = lps->maxValue() == ups->maxValue();
00423
00424 if (!minima_equal || !maxima_equal ) {
00425 delete lps;
00426 lps = new PartialSum<Card>(cur_minx, k.size(), k, false);
00427 delete ups;
00428 ups = new PartialSum<Card>(cur_minx, k.size(), k, true);
00429 }
00430
00431
00432
00433 assert(lps->minValue() <= x[nu[0]].min());
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447 HallInfo* hall = r.alloc<HallInfo>(2 * n + 2);
00448 Rank* rank = r.alloc<Rank>(n);
00449
00450 int nb = 0;
00451
00452 int min = x[nu[0]].min();
00453 int max = x[mu[0]].max() + 1;
00454 int last = lps->firstValue + 1;
00455 hall[0].bounds = last;
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465 {
00466 int i = 0;
00467 int j = 0;
00468 while (true) {
00469 if (i < n && min < max) {
00470 if (min != last) {
00471 last = min;
00472 hall[++nb].bounds = last;
00473 }
00474 rank[nu[i]].min = nb;
00475 if (++i < n) {
00476 min = x[nu[i]].min();
00477 }
00478 } else {
00479 if (max != last) {
00480 last = max;
00481 hall[++nb].bounds = last;
00482 }
00483 rank[mu[j]].max = nb;
00484 if (++j == n) {
00485 break;
00486 }
00487 max = x[mu[j]].max() + 1;
00488 }
00489 }
00490 }
00491
00492 int rightmost = nb + 1;
00493 hall[rightmost].bounds = ups->lastValue + 1 ;
00494
00495 skip_lbc = true;
00496 for (int i = k.size(); i--; ) {
00497 skip_lbc &= (k[i].min() == 0);
00498 }
00499
00500 if (!card_fixed && !skip_lbc) {
00501 es_lbc = lbc<View, Card, shared>(home, x, nb, hall, rank,lps, mu, nu);
00502 GECODE_ES_CHECK(es_lbc);
00503 mod |= (es_lbc == ES_NOFIX);
00504 }
00505
00506 es_ubc = ubc<View, Card, shared>(home, x, nb, hall, rank, ups, mu, nu);
00507 GECODE_ES_CHECK(es_ubc);
00508 mod |= (es_ubc == ES_NOFIX);
00509
00510 if (isView) {
00511 GECODE_ES_CHECK((prop_card<View, Card, shared>(home, x, k, mod)));
00512 }
00513
00514 all_assigned = true;
00515 noa = 0;
00516 single = 0;
00517 for (int i = k.size(); i--; ) {
00518 count[i] = 0;
00519 }
00520
00521 for (int i = x.size(); i--; ) {
00522 bool b = x[i].assigned();
00523 all_assigned &= b;
00524 if (b) {
00525 noa++;
00526 int idx = lookupValue(k,x[i].val());
00527 count[idx]++;
00528 } else {
00529 single = i;
00530 }
00531 }
00532
00533 if (all_assigned) {
00534 for (int i = k.size(); i--; ) {
00535 int ci = count[i];
00536 if (! (k[i].min() <= ci && ci <= k[i].max())) {
00537 return ES_FAILED;
00538 } else {
00539 if (isView) {
00540 if (!k[i].assigned()) {
00541 ModEvent me = k[i].eq(home, ci);
00542 GECODE_ME_CHECK(me);
00543 mod |= k[i].assigned();
00544 }
00545 all_assigned &= k[i].assigned();
00546 }
00547 }
00548 }
00549 if (all_assigned)
00550 return ES_SUBSUMED(*this,home);
00551 }
00552
00553 return mod ? ES_NOFIX : ES_FIX;
00554 }
00555
00564 template <class View1, class View2>
00565 class SharingTest {
00566 public:
00571 static bool shared(Space& home, ViewArray<View1>& x0,
00572 ViewArray<View2>& k0) {
00573 ViewArray<View1> xc(home, x0.size()+k0.size());
00574 for (int i = 0; i < x0.size(); i++) {
00575 xc[i] = x0[i];
00576 }
00577 for (int i = x0.size(); i < x0.size()+k0.size(); i++) {
00578 xc[i] = k0[i - x0.size()].intview();
00579 }
00580 return xc.shared(home);
00581 }
00582 };
00583
00588 template <>
00589 class SharingTest<IntView,OccurBndsView> {
00590 public:
00592 static bool shared(Space& home,
00593 ViewArray<IntView>& xs, ViewArray<OccurBndsView>&) {
00594 return xs.shared(home);
00595 }
00596 };
00597
00598 template <class View, class Card, bool isView>
00599 ExecStatus
00600 Bnd<View, Card, isView>::post(Space& home,
00601 ViewArray<View>& x0,
00602 ViewArray<Card>& k0) {
00603 bool cardfix = true;
00604 bool nolbc = true;
00605 for (int i = k0.size(); i--; ) {
00606 cardfix &= k0[i].assigned();
00607 nolbc &= (k0[i].min() == 0);
00608 }
00609 if (SharingTest<View,Card>::shared(home,x0,k0)) {
00610 new (home) BndImp<View, Card, isView, true>
00611 (home, x0, k0, cardfix, nolbc);
00612 } else {
00613 new (home) BndImp<View, Card, isView, false>
00614 (home, x0, k0, cardfix, nolbc);
00615 }
00616 return ES_OK;
00617 }
00618
00619 }}}
00620
00621
00622