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