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 #include "gecode/cpltset.hh"
00039 #include "gecode/cpltset/propagators.hh"
00040
00041 using namespace Gecode::CpltSet;
00042
00043 namespace Gecode {
00044
00045 namespace CpltSet { namespace Partition {
00046
00052 template <class View>
00053 void build_partition(ViewArray<View>& x, bdd& d0) {
00054
00055 typedef Set::LubRanges<View> SetLub;
00056 namespace IR = Iter::Ranges;
00057
00058
00059 int n = x.size();
00060 for (int i = 0; i < n - 1; i++) {
00061 for (int j = i + 1; j < n; j++) {
00062 SetLub lubx(x[i]);
00063 SetLub luby(x[j]);
00064 IR::Inter<SetLub, SetLub> inter(lubx, luby);
00065 IR::ToValues<IR::Inter<SetLub, SetLub> > values(inter);
00066 IR::ValCache<IR::ToValues<IR::Inter<SetLub, SetLub> > >
00067 cache(values);
00068
00069 for (cache.last(); cache(); --cache) {
00070 int ximin = x[i].initialLubMin();
00071 int xjmin = x[j].initialLubMin();
00072 int v = cache.min();
00073 d0 &= !(x[i].element(v - ximin) & x[j].element(v - xjmin));
00074 }
00075 }
00076 }
00077
00078 unsigned int xtab = x[0].tableWidth();
00079 for (int i = n; i--;) {
00080 if (x[i].tableWidth() > xtab)
00081 xtab = x[i].tableWidth();
00082 }
00083
00084
00085
00086 for (unsigned int k = 0; k < xtab; k++) {
00087 bdd c0 = bdd_false();
00088 for (int i = 0; i < n; i++) {
00089 if (k < x[i].tableWidth())
00090 c0 |= x[i].element(k);
00091 }
00092 d0 &= (c0 % bdd_true());
00093 }
00094 }
00095
00096 template <class View0, class View1>
00097 void build_partition(ViewArray<View0>& x, View1& y, bdd& d0) {
00098
00099 typedef Set::LubRanges<View0> SetLub;
00100 namespace IR = Iter::Ranges;
00101
00102
00103 int n = x.size();
00104 for (int i = 0; i < n - 1; i++) {
00105 for (int j = i + 1; j < n; j++) {
00106 SetLub lubx(x[i]);
00107 SetLub luby(x[j]);
00108 IR::Inter<SetLub, SetLub> inter(lubx, luby);
00109 IR::ToValues<IR::Inter<SetLub, SetLub> > values(inter);
00110 IR::ValCache<IR::ToValues<IR::Inter<SetLub, SetLub> > >
00111 cache(values);
00112
00113 for (cache.last(); cache(); --cache) {
00114 int ximin = x[i].initialLubMin();
00115 int xjmin = x[j].initialLubMin();
00116 int v = cache.min();
00117 d0 &= !(x[i].element(v - ximin) & x[j].element(v - xjmin));
00118 }
00119 }
00120 }
00121
00122 unsigned int ytab = y.tableWidth();
00123 int ymin = y.initialLubMin();
00124 for (unsigned int k = 0; k < ytab; k++) {
00125 bdd c0 = bdd_false();
00126 for (int i = 0; i < n; i++) {
00127 int xmin = x[i].initialLubMin();
00128 int xmax = x[i].initialLubMax();
00129 int shift = std::max(ymin, xmin) - std::min(xmin, ymin);
00130 if (xmin <= ymin + (int) k && ymin + (int) k <= xmax) {
00131 c0 |= x[i].element(k - shift);
00132 }
00133 }
00134 d0 &= (c0 % y.element(k));
00135 }
00136 }
00137
00138 template <class View>
00139 void build_lexorder(ViewArray<View>& x, bdd& d0, CpltSetRelType lex) {
00140
00141 int n = x.size();
00142 unsigned int xtab = x[0].tableWidth();
00143
00144 for (int i = n; i--;)
00145 if (x[i].tableWidth() > xtab)
00146 xtab = x[i].tableWidth();
00147
00148
00149 for (int i = 0; i < n - 1; i++) {
00150 for (int j = i + 1; j < n; j++) {
00151 unsigned int xai_off = x[i].offset();
00152 unsigned int xaj_off = x[j].offset();
00153 switch (lex) {
00154 case SRT_LE:
00155 {
00156 d0 &= lexlt(xai_off, xaj_off, xtab, xtab - 1);
00157 break;
00158 }
00159 case SRT_GR:
00160 {
00161 d0 &= lexlt(xaj_off, xai_off, xtab, xtab - 1);
00162 break;
00163 }
00164 case SRT_LQ:
00165 {
00166 d0 &= lexlq(xai_off, xaj_off, xtab, xtab - 1);
00167 break;
00168 }
00169 case SRT_GQ:
00170 {
00171 d0 &= lexlq(xaj_off, xai_off, xtab, xtab - 1);
00172 break;
00173 }
00174 case SRT_LE_REV:
00175 {
00176 d0 &= lexltrev(xai_off, xaj_off, xtab, 0);
00177 break;
00178 }
00179 case SRT_GR_REV:
00180 {
00181 d0 &= lexltrev(xaj_off, xai_off, xtab, 0);
00182 break;
00183 }
00184 case SRT_LQ_REV:
00185 {
00186 d0 &= lexlqrev(xai_off, xaj_off, xtab, 0);
00187 break;
00188 }
00189 case SRT_GQ_REV:
00190 {
00191 d0 &= lexlqrev(xaj_off, xai_off, xtab, 0);
00192 break;
00193 }
00194 default:
00195 {
00196 throw
00197 CpltSet::InvalidRelation("partition rel not implemented");
00198 break;
00199 }
00200 }
00201 }
00202 }
00203 }
00204
00205 template <class View>
00206 void partition_post(Space* home, ViewArray<View>& x, bool withlex,
00207 CpltSetRelType lex, bool withcard, int d) {
00208
00209 if (home->failed()) return;
00210
00211 int n = x.size();
00212
00213 bdd d0 = bdd_true();
00214 build_partition(x, d0);
00215
00216
00217 if (withlex)
00218 build_lexorder(x, d0, lex);
00219
00220 if (withcard) {
00221 for (int i = n; i--; ) {
00222 unsigned int off = x[i].offset();
00223 unsigned int range = x[i].tableWidth();
00224 d0 &= cardcheck(range, off, d, d);
00225 }
00226 }
00227
00228 GECODE_ES_FAIL(home, NaryCpltSetPropagator<View>::post(home, x, d0));
00229 }
00230
00231 template <class View>
00232 void partition_post(Space* home, ViewArray<View>& x, View& y,
00233 bool, SetRelType, bool, int) {
00234 if (home->failed()) return;
00235
00236 int n = x.size();
00237
00238 bdd d0 = bdd_true();
00239 build_partition(x, y, d0);
00240
00241 ViewArray<View> naryone(home, x.size() + 1);
00242 for (int i = 0; i < n; i++)
00243 naryone[i] = x[i];
00244 naryone[n] = y;
00245
00246 GECODE_ES_FAIL(home,
00247 NaryCpltSetPropagator<View>::post(home, naryone, d0));
00248 }
00249
00250 template <class View0, class View1>
00251 void partition_post(Space* home, ViewArray<View0>& x, View1& y,
00252 bool withlex, SetRelType lex,
00253 bool withcard, int d) {
00254 if (home->failed()) return;
00255
00256 bdd d0 = bdd_true();
00257 build_partition(x, y, d0);
00258
00259 GECODE_ES_FAIL(home,
00260 (NaryOneCpltSetPropagator<View0, View1>::post(home, x, y, d0)));
00261 }
00262
00263 template <class View>
00264 void partition_post(Space* home, ViewArray<View>& x, bool,
00265 SetRelType, bool withcard, int d) {
00266 if (home->failed()) return;
00267
00268 int n = x.size();
00269
00270 int minx = x[0].initialLubMin();
00271 int maxx = x[0].initialLubMax();
00272 unsigned int xtab = x[0].tableWidth();
00273 for (int i = n; i--;) {
00274 if (x[i].initialLubMin() < minx) {
00275 minx = x[i].initialLubMin();
00276 }
00277 if (x[i].initialLubMax() > maxx) {
00278 maxx = x[i].initialLubMax();
00279 }
00280 if (x[i].tableWidth() > xtab) {
00281 xtab = x[i].tableWidth();
00282 }
00283 }
00284
00285
00286 bdd d0 = bdd_true();
00287
00288 for (int i = 0; i < n - 1; i++) {
00289 for (int j = i + 1; j < n; j++) {
00290 Set::LubRanges<View> lubx(x[i]);
00291 Set::LubRanges<View> luby(x[j]);
00292 Gecode::Iter::Ranges::Inter<Set::LubRanges<View>,
00293 Set::LubRanges<View> > inter(lubx, luby);
00294 Gecode::Iter::Ranges::ToValues<
00295 Gecode::Iter::Ranges::Inter<Set::LubRanges<View>,
00296 Set::LubRanges<View> > > values(inter);
00297 Gecode::Iter::Ranges::ValCache<
00298 Gecode::Iter::Ranges::ToValues<
00299 Gecode::Iter::Ranges::Inter<Set::LubRanges<View>,
00300 Set::LubRanges<View> > > > cache(values);
00301 cache.last();
00302 for (; cache(); --cache) {
00303 int ximin = x[i].initialLubMin();
00304 int xjmin = x[j].initialLubMin();
00305 int v = cache.min();
00306 d0 &= !(x[i].element(v - ximin) & x[j].element(v - xjmin));
00307 }
00308
00309 }
00310 }
00311
00312
00313
00314
00315 for (unsigned int k = 0; k < xtab; k++) {
00316 bdd c0 = bdd_false();
00317 for (int i = 0; i < n; i++) {
00318 if (k < x[i].tableWidth()) {
00319 c0 |= x[i].element(k);
00320 }
00321 }
00322 d0 &= (c0 % bdd_true());
00323 }
00324
00325 if (withcard) {
00326 for (int i = n; i--; ) {
00327 unsigned int off = x[i].offset();
00328 unsigned int range = x[i].tableWidth();
00329 d0 &= cardcheck(range, off, d, d);
00330 }
00331 }
00332
00333 GECODE_ES_FAIL(home, NaryCpltSetPropagator<View>::post(home, x, d0));
00334 }
00335
00336 template <class Rel>
00337 forceinline void
00338 partition_con(Space* home, const CpltSetVarArgs& x, bool withlex, Rel lex,
00339 bool withcard, int d) {
00340 ViewArray<CpltSetView> bv(home, x);
00341 partition_post(home, bv, withlex, lex, withcard, d);
00342 }
00343
00344
00345 template <class Rel>
00346 forceinline void
00347 partition_con(Space* home, const CpltSetVarArgs& x, const CpltSetVar& y,
00348 bool withlex, Rel lex, bool withcard, int d) {
00349 ViewArray<CpltSetView> bv(home, x);
00350 CpltSetView yv(y);
00351 partition_post(home, bv, yv, withlex, lex, withcard, d);
00352 }
00353
00354 }}
00355
00356 using namespace CpltSet::Partition;
00357
00358 void partition(Space* home, const CpltSetVarArgs& x) {
00359 partition_con(home, x, false, SRT_EQ, false, -1);
00360 }
00361
00362 void partition(Space* home, const CpltSetVarArgs& x, const CpltSetVar& y) {
00363 partition_con(home, x, y, false, SRT_EQ, false, -1);
00364 }
00365
00366 void partitionLex(Space* home, const CpltSetVarArgs& x,
00367 CpltSetRelType lex) {
00368 partition_con(home, x, true, lex, false, -1);
00369 }
00370
00371 void partitionLexCard(Space* home, const CpltSetVarArgs& x,
00372 CpltSetRelType lex, unsigned int c) {
00373 Set::Limits::check(c, "CpltSet::partitionLexCard");
00374 partition_con(home, x, true, lex, true, c);
00375 }
00376
00377 void partitionCard(Space* home, const CpltSetVarArgs& x, unsigned int c) {
00378 Set::Limits::check(c, "CpltSet::partitionCard");
00379 partition_con(home, x, false, SRT_EQ, true, c);
00380 }
00381 }
00382
00383