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
00039
00040
00041
00042
00043
00044
00045 #include <gecode/set.hh>
00046 #include <gecode/int.hh>
00047
00048 namespace Gecode { namespace Set { namespace Int {
00049
00050 template<class View>
00051 forceinline
00052 MinElement<View>::MinElement(Home home, View y0, Gecode::Int::IntView y1)
00053 : MixBinaryPropagator<View,PC_SET_ANY,Gecode::Int::IntView,Gecode::Int::PC_INT_BND> (home, y0, y1) {}
00054
00055 template<class View>
00056 forceinline ExecStatus
00057 MinElement<View>::post(Home home, View x0, Gecode::Int::IntView x1) {
00058 GECODE_ME_CHECK(x0.cardMin(home,1));
00059 (void) new (home) MinElement(home,x0,x1);
00060 return ES_OK;
00061 }
00062
00063 template<class View>
00064 forceinline
00065 MinElement<View>::MinElement(Space& home, bool share, MinElement& p)
00066 : MixBinaryPropagator<View,PC_SET_ANY,Gecode::Int::IntView,Gecode::Int::PC_INT_BND> (home, share, p) {}
00067
00068 template<class View>
00069 Actor*
00070 MinElement<View>::copy(Space& home, bool share) {
00071 return new (home) MinElement(home,share,*this);
00072 }
00073
00074 template<class View>
00075 ExecStatus
00076 MinElement<View>::propagate(Space& home, const ModEventDelta&) {
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088 {
00089 LubRanges<View> ub(x0);
00090 GECODE_ME_CHECK(x1.inter_r(home,ub,false));
00091 }
00092 GECODE_ME_CHECK(x1.lq(home,x0.glbMin()));
00093
00094 assert(x0.cardMin()>=1);
00095
00096 {
00098 unsigned int size = 0;
00099 int maxN = BndSet::MAX_OF_EMPTY;
00100 for (LubRanges<View> ubr(x0); ubr(); ++ubr, ++size) {}
00101 Region r(home);
00102 int* ub = r.alloc<int>(size*2);
00103 int i=0;
00104 for (LubRanges<View> ubr(x0); ubr(); ++ubr, ++i) {
00105 ub[2*i] = ubr.min();
00106 ub[2*i+1] = ubr.max();
00107 }
00108 unsigned int x0cm = x0.cardMin()-1;
00109 for (unsigned int i=size; i--;) {
00110 unsigned int width = static_cast<unsigned int>(ub[2*i+1]-ub[2*i]+1);
00111 if (width > x0cm) {
00112 maxN = static_cast<int>(ub[2*i+1]-x0cm);
00113 break;
00114 }
00115 x0cm -= width;
00116 }
00117 GECODE_ME_CHECK(x1.lq(home,maxN));
00118 }
00119
00120 GECODE_ME_CHECK( x0.exclude(home,
00121 Limits::min, x1.min()-1) );
00122
00123 if (x1.assigned()) {
00124 GECODE_ME_CHECK(x0.include(home,x1.val()));
00125 GECODE_ME_CHECK(x0.exclude(home,
00126 Limits::min, x1.val()-1));
00127 return home.ES_SUBSUMED(*this);
00128 }
00129
00130 return ES_FIX;
00131 }
00132
00133
00134 template<class View>
00135 forceinline
00136 NotMinElement<View>::NotMinElement(Home home, View y0,
00137 Gecode::Int::IntView y1)
00138 : MixBinaryPropagator<View,PC_SET_ANY,
00139 Gecode::Int::IntView,Gecode::Int::PC_INT_DOM> (home, y0, y1) {}
00140
00141 template<class View>
00142 forceinline ExecStatus
00143 NotMinElement<View>::post(Home home, View x0, Gecode::Int::IntView x1) {
00144 (void) new (home) NotMinElement(home,x0,x1);
00145 return ES_OK;
00146 }
00147
00148 template<class View>
00149 forceinline
00150 NotMinElement<View>::NotMinElement(Space& home, bool share,
00151 NotMinElement& p)
00152 : MixBinaryPropagator<View,PC_SET_ANY,
00153 Gecode::Int::IntView,Gecode::Int::PC_INT_DOM> (home, share, p) {}
00154
00155 template<class View>
00156 Actor*
00157 NotMinElement<View>::copy(Space& home, bool share) {
00158 return new (home) NotMinElement(home,share,*this);
00159 }
00160
00161 template<class View>
00162 ExecStatus
00163 NotMinElement<View>::propagate(Space& home, const ModEventDelta&) {
00164
00165
00166
00167
00168 if ((x0.cardMax() == 0) ||
00169 ((x1.max() < x0.lubMin()) || (x1.min() > x0.lubMax())) ||
00170 ((x0.glbSize() > 0) && (x0.glbMin() < x1.min())))
00171 return home.ES_SUBSUMED(*this);
00172
00173
00174 if (x1.assigned() && x1.val()==x0.lubMin()) {
00175 GECODE_ME_CHECK(x0.exclude(home,x1.val()));
00176 return home.ES_SUBSUMED(*this);
00177 }
00178
00179
00180 if (x0.glbMin() == x0.lubMin()) {
00181 GECODE_ME_CHECK(x1.nq(home,x0.glbMin()));
00182 return home.ES_SUBSUMED(*this);
00183 }
00184
00185
00186
00187 if (x1.assigned() && x0.glbSize() > 0 && x1.val()==x0.glbMin()) {
00188 unsigned int oldGlbSize = x0.glbSize();
00189
00190 UnknownRanges<View> ur(x0);
00191 assert(ur());
00192
00193
00194
00195
00196
00197
00198 if (ur.width()==1) {
00199 int i=ur.min();
00200 ++ur;
00201 if (!ur() || ur.min()>x1.val()) {
00202 GECODE_ME_CHECK(x0.include(home,i));
00203 return home.ES_SUBSUMED(*this);
00204 }
00205 }
00206 GECODE_ME_CHECK(x0.cardMin(home, oldGlbSize+1));
00207 }
00208
00209 {
00210 LubRanges<View> ub(x0);
00211 Gecode::Int::ViewRanges<Gecode::Int::IntView> d(x1);
00212 Gecode::Iter::Ranges::Inter<LubRanges<View>,
00213 Gecode::Int::ViewRanges<Gecode::Int::IntView> > ir(ub,d);
00214 if (!ir()) return home.ES_SUBSUMED(*this);
00215 }
00216
00217
00218
00219 {
00220
00221
00222
00223
00224
00225 int num_ranges = 0;
00226 for (LubRanges<View> ur(x0); ur(); ++ur, ++num_ranges) {}
00227
00228 Region r(home);
00229 int* _ur = r.alloc<int>(num_ranges*2);
00230
00231 int i = 0;
00232 for (LubRanges<View> ur(x0); ur(); ++ur, ++i) {
00233 _ur[2*i ] = ur.min();
00234 _ur[2*i+1] = ur.max();
00235 }
00236
00237
00238 unsigned int n = x0.cardMin();
00239 int nth_largest = BndSet::MAX_OF_EMPTY;
00240 for (int i=num_ranges; i--; ) {
00241
00242 unsigned int num_values = static_cast<unsigned int>(_ur[2*i+1]-_ur[2*i]+1);
00243
00244 if (num_values >= n) {
00245
00246 nth_largest = static_cast<int>(_ur[2*i+1]-n+1);
00247 break;
00248 }
00249
00250 n -= num_values;
00251 }
00252
00253 if (x1.min() > nth_largest)
00254 return home.ES_SUBSUMED(*this);
00255 }
00256 return ES_FIX;
00257 }
00258
00259 template<class View>
00260 forceinline
00261 ReMinElement<View>::ReMinElement(Home home, View y0, Gecode::Int::IntView y1,
00262 Gecode::Int::BoolView b2)
00263 : Gecode::Int::ReMixBinaryPropagator<View,PC_SET_ANY,
00264 Gecode::Int::IntView,Gecode::Int::PC_INT_DOM,
00265 Gecode::Int::BoolView> (home, y0, y1, b2) {}
00266
00267 template<class View>
00268 forceinline ExecStatus
00269 ReMinElement<View>::post(Home home, View x0, Gecode::Int::IntView x1,
00270 Gecode::Int::BoolView b2) {
00271 (void) new (home) ReMinElement(home,x0,x1,b2);
00272 return ES_OK;
00273 }
00274
00275 template<class View>
00276 forceinline
00277 ReMinElement<View>::ReMinElement(Space& home, bool share, ReMinElement& p)
00278 : Gecode::Int::ReMixBinaryPropagator<View,PC_SET_ANY,
00279 Gecode::Int::IntView,Gecode::Int::PC_INT_DOM,
00280 Gecode::Int::BoolView> (home, share, p) {}
00281
00282 template<class View>
00283 Actor*
00284 ReMinElement<View>::copy(Space& home, bool share) {
00285 return new (home) ReMinElement(home,share,*this);
00286 }
00287
00288 template<class View>
00289 ExecStatus
00290 ReMinElement<View>::propagate(Space& home, const ModEventDelta&) {
00291
00292 if (b.one())
00293 GECODE_REWRITE(*this, (MinElement<View>::post(home(*this),x0,x1)));
00294 if (b.zero())
00295 GECODE_REWRITE(*this, (NotMinElement<View>::post(home(*this),x0,x1)));
00296
00297
00298
00299
00300 if ((x0.cardMax() == 0) ||
00301 ((x1.max() < x0.lubMin()) || (x1.min() > x0.lubMax())) ||
00302 ((x0.glbSize() > 0) && (x0.glbMin() < x1.min())))
00303 {
00304 GECODE_ME_CHECK(b.zero(home));
00305 return home.ES_SUBSUMED(*this);
00306 }
00307
00308 if (x0.glbMin() == x0.lubMin()) {
00309
00310 if (x1.assigned()) {
00311 if (x1.val() == x0.glbMin()) {
00312 GECODE_ME_CHECK(b.one(home));
00313 } else {
00314 GECODE_ME_CHECK(b.zero(home));
00315 }
00316 return home.ES_SUBSUMED(*this);
00317 }
00318
00319 else if ((x0.glbMin() < x1.min()) ||
00320 (x0.glbMin() > x1.max()) ||
00321 !x1.in(x0.glbMin()))
00322 {
00323 GECODE_ME_CHECK(b.zero(home));
00324 return home.ES_SUBSUMED(*this);
00325 }
00326 }
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381 return ES_FIX;
00382 }
00383
00384 template<class View>
00385 forceinline
00386 MaxElement<View>::MaxElement(Home home, View y0, Gecode::Int::IntView y1)
00387 : MixBinaryPropagator<View,PC_SET_ANY,
00388 Gecode::Int::IntView,Gecode::Int::PC_INT_BND> (home, y0, y1) {}
00389
00390 template<class View>
00391 forceinline
00392 MaxElement<View>::MaxElement(Space& home, bool share, MaxElement& p)
00393 : MixBinaryPropagator<View,PC_SET_ANY,
00394 Gecode::Int::IntView,Gecode::Int::PC_INT_BND> (home, share, p) {}
00395
00396 template<class View>
00397 ExecStatus
00398 MaxElement<View>::post(Home home, View x0,
00399 Gecode::Int::IntView x1) {
00400 GECODE_ME_CHECK(x0.cardMin(home,1));
00401 (void) new (home) MaxElement(home,x0,x1);
00402 return ES_OK;
00403 }
00404
00405 template<class View>
00406 Actor*
00407 MaxElement<View>::copy(Space& home, bool share) {
00408 return new (home) MaxElement(home,share,*this);
00409 }
00410
00411 template<class View>
00412 ExecStatus
00413 MaxElement<View>::propagate(Space& home, const ModEventDelta&) {
00414 LubRanges<View> ub(x0);
00415 GECODE_ME_CHECK(x1.inter_r(home,ub,false));
00416 GECODE_ME_CHECK(x1.gq(home,x0.glbMax()));
00417 assert(x0.cardMin()>=1);
00418 GECODE_ME_CHECK(x1.gq(home,x0.lubMinN(x0.cardMin()-1)));
00419 GECODE_ME_CHECK(x0.exclude(home,
00420 x1.max()+1,Limits::max) );
00421
00422 if (x1.assigned()) {
00423 GECODE_ME_CHECK(x0.include(home,x1.val()));
00424 GECODE_ME_CHECK( x0.exclude(home,
00425 x1.val()+1,Limits::max) );
00426 return home.ES_SUBSUMED(*this);
00427 }
00428
00429 return ES_FIX;
00430 }
00431
00432 template<class View>
00433 forceinline
00434 NotMaxElement<View>::NotMaxElement(Home home, View y0,
00435 Gecode::Int::IntView y1)
00436 : MixBinaryPropagator<View,PC_SET_ANY,
00437 Gecode::Int::IntView,Gecode::Int::PC_INT_DOM> (home, y0, y1) {}
00438
00439 template<class View>
00440 forceinline
00441 NotMaxElement<View>::NotMaxElement(Space& home, bool share,
00442 NotMaxElement& p)
00443 : MixBinaryPropagator<View,PC_SET_ANY,
00444 Gecode::Int::IntView,Gecode::Int::PC_INT_DOM> (home, share, p) {}
00445
00446 template<class View>
00447 ExecStatus
00448 NotMaxElement<View>::post(Home home, View x0, Gecode::Int::IntView x1) {
00449 (void) new (home) NotMaxElement(home,x0,x1);
00450 return ES_OK;
00451 }
00452
00453 template<class View>
00454 Actor*
00455 NotMaxElement<View>::copy(Space& home, bool share) {
00456 return new (home) NotMaxElement(home,share,*this);
00457 }
00458
00459 template<class View>
00460 ExecStatus
00461 NotMaxElement<View>::propagate(Space& home, const ModEventDelta&) {
00462
00463
00464
00465
00466 if ((x0.cardMax() == 0) ||
00467 ((x1.max() < x0.lubMin()) || (x1.min() > x0.lubMax())) ||
00468 ((x0.glbSize() > 0) && (x0.glbMax() > x1.max())))
00469 return home.ES_SUBSUMED(*this);
00470
00471
00472 if (x1.assigned() && x1.val()==x0.lubMax()) {
00473 GECODE_ME_CHECK(x0.exclude(home,x1.val()));
00474 return home.ES_SUBSUMED(*this);
00475 }
00476
00477
00478 if (x0.glbMax() == x0.lubMax()) {
00479 GECODE_ME_CHECK(x1.nq(home,x0.glbMax()));
00480 return home.ES_SUBSUMED(*this);
00481 }
00482
00483
00484
00485 if (x1.assigned() && x0.glbSize() > 0 && x1.val()==x0.glbMax()) {
00486 unsigned int oldGlbSize = x0.glbSize();
00487
00488 UnknownRanges<View> ur(x0);
00489
00490
00491 while (ur.max() < x1.val()) {
00492 assert(ur());
00493 ++ur;
00494 };
00495
00496
00497 if (ur.width() == 1) {
00498 int i = ur.min();
00499 ++ur;
00500 if (!ur()) {
00501
00502 GECODE_ME_CHECK(x0.include(home,i));
00503 return home.ES_SUBSUMED(*this);
00504 }
00505 }
00506 GECODE_ME_CHECK(x0.cardMin(home, oldGlbSize+1));
00507 }
00508
00509 {
00510 LubRanges<View> ub(x0);
00511 Gecode::Int::ViewRanges<Gecode::Int::IntView> d(x1);
00512 Gecode::Iter::Ranges::Inter<LubRanges<View>,
00513 Gecode::Int::ViewRanges<Gecode::Int::IntView> > ir(ub,d);
00514 if (!ir()) return home.ES_SUBSUMED(*this);
00515 }
00516
00517
00518
00519 {
00520 unsigned int n = x0.cardMin();
00521 int nth_smallest = BndSet::MIN_OF_EMPTY;
00522 for (LubRanges<View> ur(x0); ur(); ++ur) {
00523 if (ur.width() >= n) {
00524
00525 nth_smallest = static_cast<int>(ur.min() + n - 1);
00526 break;
00527 }
00528
00529 n -= ur.width();
00530 }
00531
00532 if (x1.max() < nth_smallest)
00533 return home.ES_SUBSUMED(*this);
00534 }
00535 return ES_FIX;
00536 }
00537
00538 template<class View>
00539 forceinline
00540 ReMaxElement<View>::ReMaxElement(Home home, View y0, Gecode::Int::IntView y1,
00541 Gecode::Int::BoolView b2)
00542 : Gecode::Int::ReMixBinaryPropagator<View,PC_SET_ANY,
00543 Gecode::Int::IntView,Gecode::Int::PC_INT_DOM,
00544 Gecode::Int::BoolView> (home, y0, y1, b2) {}
00545
00546 template<class View>
00547 forceinline
00548 ReMaxElement<View>::ReMaxElement(Space& home, bool share, ReMaxElement& p)
00549 : Gecode::Int::ReMixBinaryPropagator<View,PC_SET_ANY,
00550 Gecode::Int::IntView,Gecode::Int::PC_INT_DOM,
00551 Gecode::Int::BoolView> (home, share, p) {}
00552
00553 template<class View>
00554 ExecStatus
00555 ReMaxElement<View>::post(Home home, View x0,
00556 Gecode::Int::IntView x1,
00557 Gecode::Int::BoolView b2) {
00558 (void) new (home) ReMaxElement(home,x0,x1,b2);
00559 return ES_OK;
00560 }
00561
00562 template<class View>
00563 Actor*
00564 ReMaxElement<View>::copy(Space& home, bool share) {
00565 return new (home) ReMaxElement(home,share,*this);
00566 }
00567
00568 template<class View>
00569 ExecStatus
00570 ReMaxElement<View>::propagate(Space& home, const ModEventDelta&) {
00571
00572 if (b.one())
00573 GECODE_REWRITE(*this, (MaxElement<View>::post(home(*this),x0,x1)));
00574 if (b.zero())
00575 GECODE_REWRITE(*this, (NotMaxElement<View>::post(home(*this),x0,x1)));
00576
00577
00578
00579
00580 if ((x0.cardMax() == 0) ||
00581 ((x1.max() < x0.lubMin()) || (x1.min() > x0.lubMax())) ||
00582 ((x0.glbSize() > 0) && (x0.glbMax() > x1.max())))
00583 {
00584 GECODE_ME_CHECK(b.zero(home));
00585 return home.ES_SUBSUMED(*this);
00586 }
00587
00588 if (x0.glbMax() == x0.lubMax()) {
00589
00590 if (x1.assigned()) {
00591 if (x1.val() == x0.glbMax()) {
00592 GECODE_ME_CHECK(b.one(home));
00593 } else {
00594 GECODE_ME_CHECK(b.zero(home));
00595 }
00596 return home.ES_SUBSUMED(*this);
00597 }
00598
00599 else if ((x0.glbMax() < x1.min()) ||
00600 (x0.glbMax() > x1.max()) ||
00601 !x1.in(x0.glbMax()))
00602 {
00603 GECODE_ME_CHECK(b.zero(home));
00604 return home.ES_SUBSUMED(*this);
00605 }
00606 }
00607
00608 {
00609 LubRanges<View> ub(x0);
00610 Gecode::Int::ViewRanges<Gecode::Int::IntView> d(x1);
00611 Gecode::Iter::Ranges::Inter<LubRanges<View>,
00612 Gecode::Int::ViewRanges<Gecode::Int::IntView> > ir(ub,d);
00613 if (!ir()) {
00614 GECODE_ME_CHECK(b.zero(home));
00615 return home.ES_SUBSUMED(*this);
00616 }
00617 }
00618
00619
00620
00621 {
00622 unsigned int n = x0.cardMin();
00623 int nth_smallest = BndSet::MIN_OF_EMPTY;
00624 for (LubRanges<View> ur(x0); ur(); ++ur) {
00625 if (ur.width() >= n)
00626 {
00627
00628 nth_smallest = static_cast<int>(ur.min() + n - 1);
00629 break;
00630 }
00631
00632 n -= ur.width();
00633 }
00634
00635 if (x1.max() < nth_smallest) {
00636 GECODE_ME_CHECK(b.zero(home));
00637 return home.ES_SUBSUMED(*this);
00638 }
00639 }
00640 return ES_FIX;
00641 }
00642
00643 }}}
00644
00645