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 Set { namespace Rel {
00039
00043 class CharacteristicSets {
00044 protected:
00046 unsigned int xsize;
00048 Support::BitSetBase b;
00050 int* ub;
00052 bool xlm;
00054 bool xum;
00056 bool ylm;
00058 bool yum;
00060 void set(int i, bool j) {
00061 if (j)
00062 b.set(i);
00063 else
00064 b.clear(i);
00065 }
00066
00068 class CSIter {
00069 public:
00071 CharacteristicSets* cs;
00073 unsigned int i;
00075 int xoff;
00077 int yoff;
00079 void operator++ (void) {
00080 i++;
00081 while (i<cs->xsize && !cs->b.get(xoff+2*i+yoff))
00082 i++;
00083 }
00085 CSIter(void) {}
00087 CSIter(CharacteristicSets& cs0, int xoff0, int yoff0)
00088 : cs(&cs0), i(-1), xoff(xoff0), yoff(yoff0) {
00089 ++(*this);
00090 }
00092 bool operator() (void) const { return i<cs->xsize; }
00094 int val(void) const { return cs->ub[i]; }
00095 };
00096
00097 public:
00099 template<class View0, class View1>
00100 CharacteristicSets(Region& re, View0 x, View1 y);
00101
00103 bool xmin(int i) const { return b.get(2*i); }
00105 bool xmax(int i) const { return b.get(2*i+1); }
00107 bool ymin(int i) const { return b.get(2*xsize+2*i); }
00109 bool ymax(int i) const { return b.get(2*xsize+2*i+1); }
00110
00112 void xmin(int i, bool j) { set(2*i,j); }
00114 void xmax(int i, bool j) { set(2*i+1,j); }
00116 void ymin(int i, bool j) { set(2*xsize+2*i,j); }
00118 void ymax(int i, bool j) { set(2*xsize+2*i+1,j); }
00119
00121 ModEvent xlq(int i, bool j) {
00122 if (!j) {
00123 if (xmin(i)) return ME_SET_FAILED;
00124 if (xmax(i)) {
00125 xmax(i,false);
00126 xum=true;
00127 }
00128 }
00129 return ME_SET_NONE;
00130 }
00132 ModEvent xgq(int i, bool j) {
00133 if (j) {
00134 if (!xmax(i)) return ME_SET_FAILED;
00135 if (!xmin(i)) {
00136 xmin(i,true);
00137 xlm=true;
00138 }
00139 }
00140 return ME_SET_NONE;
00141 }
00143 ModEvent ylq(int i, bool j) {
00144 if (!j) {
00145 if (ymin(i)) return ME_SET_FAILED;
00146 if (ymax(i)) {
00147 ymax(i,false);
00148 yum=true;
00149 }
00150 }
00151 return ME_SET_NONE;
00152 }
00154 ModEvent ygq(int i, bool j) {
00155 if (j) {
00156 if (!ymax(i)) return ME_SET_FAILED;
00157 if (!ymin(i)) {
00158 ymin(i,true);
00159 ylm=true;
00160 }
00161 }
00162 return ME_SET_NONE;
00163 }
00164
00166 int size(void) const { return xsize; }
00167
00169 template<class View0, class View1>
00170 ExecStatus prune(Space& home, View0 x, View1 y) {
00171 if (xlm) {
00172 CSIter i(*this,0,0);
00173 Iter::Values::ToRanges<CSIter> ir(i);
00174 GECODE_ME_CHECK(x.includeI(home,ir));
00175 }
00176 if (xum) {
00177 CSIter i(*this,0,1);
00178 Iter::Values::ToRanges<CSIter> ir(i);
00179 GECODE_ME_CHECK(x.intersectI(home,ir));
00180 }
00181 if (ylm) {
00182 CSIter i(*this,2*xsize,0);
00183 Iter::Values::ToRanges<CSIter> ir(i);
00184 GECODE_ME_CHECK(y.includeI(home,ir));
00185 }
00186 if (yum) {
00187 CSIter i(*this,2*xsize,1);
00188 Iter::Values::ToRanges<CSIter> ir(i);
00189 GECODE_ME_CHECK(y.intersectI(home,ir));
00190 }
00191 return ES_OK;
00192 }
00193
00194 };
00195
00196 template<class View0, class View1>
00197 CharacteristicSets::CharacteristicSets(Region& re,View0 x, View1 y)
00198 : xlm(false), xum(false), ylm(false), yum(false) {
00199 LubRanges<View0> xlub(x);
00200 LubRanges<View1> ylub(y);
00201 Iter::Ranges::Union<LubRanges<View0>,LubRanges<View1> > xylub(xlub,ylub);
00202 Iter::Ranges::Cache xylubc(re,xylub);
00203 xsize = Iter::Ranges::size(xylubc);
00204 b.init(re,4*xsize);
00205 ub = re.alloc<int>(xsize);
00206 xylubc.reset();
00207 Iter::Ranges::ToValues<Iter::Ranges::Cache> xylubv(xylubc);
00208 LubRanges<View0> xur(x);
00209 GlbRanges<View0> xlr(x);
00210 LubRanges<View1> yur(y);
00211 GlbRanges<View1> ylr(y);
00212 Iter::Ranges::ToValues<LubRanges<View0> > xuv(xur);
00213 Iter::Ranges::ToValues<GlbRanges<View0> > xlv(xlr);
00214 Iter::Ranges::ToValues<LubRanges<View1> > yuv(yur);
00215 Iter::Ranges::ToValues<GlbRanges<View1> > ylv(ylr);
00216 for (int i=0; xylubv(); ++xylubv, ++i) {
00217 ub[i] = xylubv.val();
00218 if (xlv() && xylubv.val()==xlv.val()) {
00219 b.set(2*i);
00220 ++xlv;
00221 }
00222 if (xuv() && xylubv.val()==xuv.val()) {
00223 b.set(2*i+1);
00224 ++xuv;
00225 }
00226 if (ylv() && xylubv.val()==ylv.val()) {
00227 b.set(2*xsize+2*i);
00228 ++ylv;
00229 }
00230 if (yuv() && xylubv.val()==yuv.val()) {
00231 b.set(2*xsize+2*i+1);
00232 ++yuv;
00233 }
00234 }
00235 }
00236
00237 template<class View0, class View1, bool strict>
00238 forceinline
00239 Lq<View0,View1,strict>::Lq(Home home, View0 x, View1 y)
00240 : MixBinaryPropagator<View0,PC_SET_ANY,View1,PC_SET_ANY>(home,x,y) {}
00241
00242 template<class View0, class View1, bool strict>
00243 forceinline
00244 Lq<View0,View1,strict>::Lq(Space& home, bool share, Lq& p)
00245 : MixBinaryPropagator<View0,PC_SET_ANY,View1,PC_SET_ANY>(home,share,p) {}
00246
00247 template<class View0, class View1, bool strict>
00248 ExecStatus
00249 Lq<View0,View1,strict>::post(Home home, View0 x, View1 y) {
00250 if (strict)
00251 GECODE_ME_CHECK(y.cardMin(home,1));
00252 (void) new (home) Lq(home,x,y);
00253 return ES_OK;
00254 }
00255
00256 template<class View0, class View1, bool strict>
00257 Actor*
00258 Lq<View0,View1,strict>::copy(Space& home, bool share) {
00259 return new (home) Lq(home,share,*this);
00260 }
00261
00262 template<class View0, class View1, bool strict>
00263 ExecStatus
00264 Lq<View0,View1,strict>::propagate(Space& home, const ModEventDelta&) {
00265 if ( (!strict) && x1.cardMax()==0) {
00266 GECODE_ME_CHECK(x0.cardMax(home,0));
00267 }
00268
00269 if (x0.cardMax()==0) {
00270 return home.ES_SUBSUMED(*this);
00271 }
00272
00273 if (x0.glbMin() < x1.lubMin())
00274 return ES_FAILED;
00275 if (x1.glbMin() < x0.lubMin())
00276 return home.ES_SUBSUMED(*this);
00277
00278 bool assigned = x0.assigned() && x1.assigned();
00279
00280 Region re(home);
00281 CharacteristicSets cs(re,x0,x1);
00282
00283
00284
00285
00286
00287 int i=0;
00288 int firsti=0;
00289 int n=cs.size();
00290 while ((i<n) && cs.xmin(i) == cs.ymax(i)) {
00291
00292 GECODE_ME_CHECK(cs.xlq(i,cs.ymax(i)));
00293 GECODE_ME_CHECK(cs.ygq(i,cs.xmin(i)));
00294 i++;
00295 }
00296
00297 if (i == n) {
00298 if (strict) {
00299 return ES_FAILED;
00300 } else {
00301 GECODE_ES_CHECK(cs.prune(home,x0,x1));
00302 return home.ES_SUBSUMED(*this);
00303 }
00304 }
00305
00306
00307 GECODE_ME_CHECK(cs.xlq(i,cs.ymax(i)));
00308 GECODE_ME_CHECK(cs.ygq(i,cs.xmin(i)));
00309
00310 if (cs.xmax(i) < cs.ymin(i)) {
00311 GECODE_ES_CHECK(cs.prune(home,x0,x1));
00312 return home.ES_SUBSUMED(*this);
00313 }
00314
00315 firsti=i;
00316
00317
00318
00319
00320
00321
00322 i++;
00323
00324 while ((i < n) &&
00325 (cs.xmin(i) == cs.ymax(i)) &&
00326 (cs.xmax(i) == cs.ymin(i))) {
00327 i++;
00328 }
00329
00330 if (i == n) {
00331 if (strict)
00332 goto rewrite_le;
00333 else
00334 goto rewrite_lq;
00335 }
00336
00337 if (cs.xmax(i) < cs.ymin(i))
00338 goto rewrite_lq;
00339
00340 if (cs.xmin(i) > cs.ymax(i))
00341 goto rewrite_le;
00342
00343 if (cs.xmax(i) <= cs.ymin(i)) {
00344
00345
00346
00347
00348
00349
00350 i++;
00351
00352 while ((i < n) && (cs.xmax(i) == cs.ymin(i))) {
00353 i++;
00354 }
00355
00356 if (i == n) {
00357 if (strict) {
00358 GECODE_ES_CHECK(cs.prune(home,x0,x1));
00359 return assigned ? home.ES_SUBSUMED(*this) : ES_NOFIX;
00360 } else {
00361 goto rewrite_lq;
00362 }
00363 }
00364
00365 if (cs.xmax(i) < cs.ymin(i))
00366 goto rewrite_lq;
00367
00368 GECODE_ES_CHECK(cs.prune(home,x0,x1));
00369 return assigned ? home.ES_SUBSUMED(*this) : ES_NOFIX;
00370 }
00371
00372 if (cs.xmin(i) >= cs.ymax(i)) {
00373
00374
00375
00376
00377
00378
00379 i++;
00380
00381 while ((i < n) && (cs.xmin(i) == cs.ymax(i))) {
00382
00383 i++;
00384 }
00385
00386 if (i == n) {
00387 if (strict) {
00388 goto rewrite_le;
00389 } else {
00390 GECODE_ES_CHECK(cs.prune(home,x0,x1));
00391 return assigned ? home.ES_SUBSUMED(*this) : ES_NOFIX;
00392 }
00393 }
00394
00395 if (cs.xmin(i) > cs.ymax(i))
00396 goto rewrite_le;
00397
00398 GECODE_ES_CHECK(cs.prune(home,x0,x1));
00399 return assigned ? home.ES_SUBSUMED(*this) : ES_NOFIX;
00400 }
00401
00402 GECODE_ES_CHECK(cs.prune(home,x0,x1));
00403 return assigned ? home.ES_SUBSUMED(*this) : ES_NOFIX;
00404
00405 rewrite_le:
00406 GECODE_ME_CHECK(cs.xlq(firsti,false));
00407 GECODE_ME_CHECK(cs.ygq(firsti,true));
00408 GECODE_ES_CHECK(cs.prune(home,x0,x1));
00409 return home.ES_SUBSUMED(*this);
00410 rewrite_lq:
00411 GECODE_ES_CHECK(cs.prune(home,x0,x1));
00412 return assigned ? home.ES_SUBSUMED(*this) : ES_NOFIX;
00413 }
00414
00415 }}}
00416
00417