00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 namespace Gecode { namespace Int { namespace GCC {
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 template <class View, class Card, bool isView>
00049 inline
00050 Dom<View, Card, isView>::Dom(Space* home, ViewArray<View>& x0,
00051 ViewArray<Card>& k0, bool cf, bool all)
00052 : Propagator(home, true), x(x0), y(home, x0),
00053 k(k0), vvg(NULL), card_fixed(cf), card_all(all) {
00054
00055
00056 x.subscribe(home, this, PC_INT_DOM);
00057 k.subscribe(home, this, PC_INT_DOM);
00058 }
00059
00060 template <class View, class Card, bool isView>
00061 forceinline
00062 Dom<View, Card, isView>::Dom(Space* home, bool share,
00063 Dom<View, Card, isView>& p)
00064 : Propagator(home, share, p), vvg(NULL),
00065 card_fixed(p.card_fixed), card_all(p.card_all) {
00066 x.update(home, share, p.x);
00067 y.update(home, share, p.y);
00068 k.update(home, share, p.k);
00069 }
00070
00071 template <class View, class Card, bool isView>
00072 size_t
00073 Dom<View, Card, isView>::dispose(Space* home) {
00074 if (!home->failed()) {
00075 x.cancel(home,this, PC_INT_DOM);
00076 k.cancel(home,this, PC_INT_DOM);
00077 }
00078 delete vvg;
00079 (void) Propagator::dispose(home);
00080 return sizeof(*this);
00081 }
00082
00083 template <class View, class Card, bool isView>
00084 void
00085 Dom<View, Card, isView>::flush(void) {
00086 delete vvg;
00087 vvg = NULL;
00088 }
00089
00090 template <class View, class Card, bool isView>
00091 Actor*
00092 Dom<View, Card, isView>::copy(Space* home, bool share) {
00093 return new (home) Dom<View, Card, isView>(home, share, *this);
00094 }
00095
00096 template <class View, class Card, bool isView>
00097 PropCost
00098 Dom<View, Card, isView>::cost(void) const {
00099
00100 unsigned int n = x.size();
00101 unsigned int d = x[n - 1].size();
00102 for (int i = n; i--; ) {
00103 if (x[i].size() > d) {
00104 d = x[i].size();
00105 }
00106 }
00107
00108 PropCost pc;
00109 if (d < 6) {
00110 pc = PC_LINEAR_LO;
00111 } else {
00112 if (6 <= d && d < n/2) {
00113 pc = PC_LINEAR_HI;
00114 }
00115 else {
00116 if (n/2 <= d && d < n*n) {
00117 pc = PC_QUADRATIC_LO;
00118 } else {
00119 pc = PC_CUBIC_LO;
00120 }
00121 }
00122 }
00123 return cost_lo(x.size(), pc);
00124
00125 }
00126
00128 template <class View, class Card, bool isView>
00129 ExecStatus
00130 Dom<View, Card, isView>::propagate(Space* home) {
00131
00132 ExecStatus es = ES_NOFIX;
00133 bool card_mod = false;
00134
00135 GECODE_AUTOARRAY(int, count, k.size());
00136 for (int i = k.size(); i--; ) {
00137 count[i] = 0;
00138 }
00139 bool all_assigned = true;
00140
00141 int noa = 0;
00142 for (int i = y.size(); i--; ) {
00143 bool b = y[i].assigned();
00144 all_assigned &= b;
00145 if (b) {
00146 noa++;
00147 int idx = lookupValue(k, y[i].val());
00148 if (idx == -1) {
00149 return ES_FAILED;
00150 }
00151 count[idx]++;
00152 if (isView) {
00153 if (k[idx].max() == 0) {
00154 return ES_FAILED;
00155 }
00156 }
00157 }
00158 }
00159
00160 if (all_assigned) {
00161 for (int i = k.size(); i--; ) {
00162 int ci = count[i];
00163 if (!(k[i].min() <= ci && ci <= k[i].max())) {
00164 return ES_FAILED;
00165 }
00166
00167 if (isView) {
00168 if (!k[i].assigned()) {
00169 ModEvent me = k[i].eq(home, ci);
00170 if (me_failed(me)) {
00171 return ES_FAILED;
00172 }
00173 }
00174 all_assigned &= k[i].assigned();
00175 card_mod |= k[i].modified();
00176 }
00177 }
00178 if (all_assigned) {
00179 return ES_SUBSUMED;
00180 }
00181 }
00182
00183
00184 if (isView) {
00185 if (noa > 0) {
00186 int n = y.size();
00187 int ks = k.size();
00188
00189 for (int i = ks; i--; ) {
00190 if (!k[i].assigned()) {
00191 int ub = n - (noa - count[i]);
00192 int lb = count[i];
00193 ModEvent melq = k[i].lq(home, ub);
00194 if (me_failed(melq)) {
00195 return ES_FAILED;
00196 }
00197 card_mod |= k[i].modified();
00198
00199 ModEvent megq = k[i].gq(home, lb);
00200 if (me_failed(megq)) {
00201 return ES_FAILED;
00202 }
00203 card_mod |= k[i].modified();
00204 }
00205 }
00206 }
00207
00208 es = prop_card<View, Card, true>(home, y, k, card_mod);
00209 if (es == ES_FAILED) {
00210 return es;
00211 }
00212
00213 int smin = 0;
00214 int smax = 0;
00215 if (!card_consistent<View, Card>(smin, smax, y, k, card_all)) {
00216 return ES_FAILED;
00217 }
00218 }
00219
00220 if (x.size() < 2) {
00221 assert(x.size() >= 0);
00222 if (x.size() == 0) {
00223 for (int j = k.size(); j--; ) {
00224 if (k[j].min() > k[j].counter() || k[j].max() < k[j].counter()) {
00225 return ES_FAILED;
00226 }
00227 }
00228 return ES_SUBSUMED;
00229 } else {
00230 if (x.size() == 1) {
00231 if (x[0].assigned()) {
00232 int v = x[0].val();
00233 int idx = lookupValue(k,v);
00234 if (idx == -1) {
00235 return ES_FAILED;
00236 }
00237 ModEvent me = k[idx].inc();
00238 if (me_failed(me)) {
00239 return ES_FAILED;
00240 }
00241 card_mod |= k[idx].modified();
00242 for (int j = k.size(); j--; ) {
00243 if (k[j].min() > k[j].counter() || k[j].max() < k[j].counter()) {
00244 return ES_FAILED;
00245 }
00246 }
00247 return ES_SUBSUMED;
00248 }
00249 }
00250 }
00251 }
00252
00253 assert(x.size() > 0);
00254
00255 bool mod = false;
00256 bool min_req_mod = false;
00257 int noe = 0;
00258 int smin = 0;
00259 int smax = 0;
00260 assert(noe >= 0);
00261 for (int i = x.size(); i--; ) {
00262 noe +=x[i].size();
00263 }
00264
00265 assert(noe > 0);
00266
00267 for (int i = k.size(); i--; ) {
00268 int ci = k[i].counter();
00269 if (ci > k[i].max() ) {
00270 return ES_FAILED;
00271 } else {
00272 smax += (k[i].max() - ci);
00273 if (ci < k[i].min()) {
00274 smin += (k[i].min() - ci);
00275 }
00276 }
00277 }
00278
00279 if (x.size() < smin) {
00280 return ES_FAILED;
00281 }
00282
00283 if (card_all) {
00284 if (smax < x.size()) {
00285 return ES_FAILED;
00286 }
00287 }
00288
00289 if (vvg == NULL) {
00290 assert(noe > 0);
00291 assert(smin >= 0);
00292 assert(smax >= 0);
00293 vvg = new VarValGraph<View, Card, isView> (x, y, k, noe, smin, smax);
00294 min_req_mod = vvg->min_require(home);
00295 if (vvg->failed()) {
00296 return ES_FAILED;
00297 }
00298
00299 bool init_ubm = vvg->template maximum_matching<UBC>();
00300 if (!init_ubm) {
00301 return ES_FAILED;
00302 }
00303
00304 if (!card_fixed) {
00305 bool init_lbm = vvg->template maximum_matching<LBC>();
00306 if (!init_lbm) {
00307 return ES_FAILED;
00308 }
00309 }
00310 } else {
00311 if (!vvg->sync()) {
00312 return ES_FAILED;
00313 }
00314 }
00315
00316 bool filter_ubc = false;
00317 bool filter_lbc = false;
00318
00319 vvg->template free_alternating_paths<UBC>();
00320 vvg->template strongly_connected_components<UBC>();
00321
00322 filter_ubc = vvg->template narrow<UBC>(home);
00323 if (vvg->failed()) {
00324 return ES_FAILED;
00325 }
00326 if (!card_fixed) {
00327 if (isView) {
00328 if (!vvg->sync()) {
00329 return ES_FAILED;
00330 }
00331 }
00332 vvg->template free_alternating_paths<LBC>();
00333 vvg->template strongly_connected_components<LBC>();
00334
00335 filter_lbc = vvg->template narrow<LBC>(home);
00336 if (vvg->failed()) {
00337 return ES_FAILED;
00338 }
00339 }
00340
00341 bool card_assigned = true;
00342 if (isView) {
00343 es = prop_card<View, Card, true>(home, y, k, card_mod);
00344 if (es == ES_FAILED) {
00345 return ES_FAILED;
00346 }
00347
00348 for (int i = k.size(); i--; ) {
00349 card_assigned &= k[i].assigned();
00350 }
00351 }
00352
00353 if (card_assigned) {
00354 if (x.size() < 2) {
00355 assert(x.size() >= 0);
00356 if (x.size() == 0) {
00357 for (int j = k.size(); j--; ) {
00358 if (k[j].min() > k[j].counter() ||
00359 k[j].max() < k[j].counter()) {
00360 return ES_FAILED;
00361 }
00362 }
00363 return ES_SUBSUMED;
00364 } else {
00365 if (x.size() == 1) {
00366 if (x[0].assigned()) {
00367 int v = x[0].val();
00368 int idx = lookupValue(k,v);
00369 if (idx == -1) {
00370 return ES_FAILED;
00371 }
00372 ModEvent me = k[idx].inc();
00373 if (me_failed(me)) {
00374 return ES_FAILED;
00375 }
00376 card_mod |= k[idx].modified();
00377
00378 for (int j = k.size(); j--; ) {
00379 if (k[j].min() > k[j].counter() ||
00380 k[j].max() < k[j].counter()) {
00381 return ES_FAILED;
00382 }
00383 }
00384 return ES_SUBSUMED;
00385 }
00386 }
00387 }
00388 }
00389 }
00390
00391 for (int i = k.size(); i--; ) {
00392 count[i] = 0;
00393 }
00394 all_assigned = true;
00395
00396 for (int i = y.size(); i--; ) {
00397 bool b = y[i].assigned();
00398 all_assigned &= b;
00399 if (b) {
00400 int idx = lookupValue(k,y[i].val());
00401 if (idx == -1) {
00402 return ES_FAILED;
00403 }
00404 count[idx]++;
00405 if (isView) {
00406 if (k[idx].max() == 0) {
00407 return ES_FAILED;
00408 }
00409 }
00410 }
00411 }
00412
00413 if (isView) {
00414 es = prop_card<View, Card, true>(home, y, k, card_mod);
00415 if (es == ES_FAILED) {
00416 return es;
00417 }
00418 }
00419
00420 if (all_assigned) {
00421 for (int i = k.size(); i--; ) {
00422 int ci = count[i];
00423 if (!(k[i].min() <= ci && ci <= k[i].max())) {
00424 return ES_FAILED;
00425 }
00426
00427 if (isView) {
00428 if (!k[i].assigned()) {
00429 ModEvent me = k[i].eq(home, ci);
00430 if (me_failed(me)) {
00431 return ES_FAILED;
00432 }
00433 }
00434 all_assigned &= k[i].assigned();
00435 card_mod |= k[i].modified();
00436 }
00437 }
00438 if (all_assigned) {
00439 return ES_SUBSUMED;
00440 }
00441 }
00442
00443 if (isView) {
00444 int smax = 0;
00445 int smin = 0;
00446 for (int i = k.size(); i--; ) {
00447 smax += k[i].max();
00448 }
00449 int ysmax = y.size() - smax;
00450 int ysmin = y.size() - smin;
00451 smax = 0;
00452 smin = 0;
00453 bool card_ass = true;
00454 for (int i = k.size(); i--; ) {
00455 int lb = ysmax + k[i].max();
00456 int ub = ysmin + k[i].min();
00457 ModEvent me = k[i].gq(home, lb);
00458 if (me_failed(me)) {
00459 return ES_FAILED;
00460 }
00461
00462 card_mod |= k[i].modified() && k[i].min() != lb;
00463 smax += k[i].max();
00464
00465 me = k[i].lq(home, ub);
00466 if (me_failed(me)) {
00467 return ES_FAILED;
00468 }
00469 card_mod |= k[i].modified();
00470 card_ass &= k[i].assigned();
00471 }
00472 if (card_ass) {
00473 if (smax < y.size() || smax > y.size()) {
00474 return ES_FAILED;
00475 }
00476 }
00477 }
00478
00479 mod = (filter_ubc || filter_lbc || min_req_mod || card_mod);
00480
00481 return mod ? ES_NOFIX : ES_FIX;
00482
00483 }
00484
00485 template <class View, class Card, bool isView>
00486 inline ExecStatus
00487 Dom<View, Card, isView>::post(Space* home, ViewArray<View>& x0,
00488 ViewArray<Card>& k0, bool all){
00489
00490 bool cardfix = true;
00491 for (int i = k0.size(); i--; ) {
00492 cardfix &= k0[i].assigned();
00493 }
00494
00495 (void) new (home) Dom<View, Card, isView>(home, x0, k0, cardfix, all);
00496 return ES_OK;
00497 }
00498
00499 }}}
00500
00501
00502
00503
00504