00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <climits>
00023
00024 #include "gecode/support/dynamic-array.hh"
00025 #include "gecode/support/static-stack.hh"
00026
00027 #include "gecode/iter.hh"
00028
00029 namespace Gecode { namespace Int { namespace Distinct {
00030
00038 template <class T>
00039 class CombPtrFlag {
00040 private:
00042 ptrdiff_t cpf;
00043 public:
00045 CombPtrFlag(T* p1, T* p2);
00047 void init(T* p1, T* p2);
00049 T* ptr(T* p) const;
00051 int is_set(void) const;
00053 void set(void);
00055 void unset(void);
00056 };
00057
00062 class BiLink {
00063 private:
00064 BiLink* _prev; BiLink* _next;
00065 public:
00066 BiLink(void);
00067
00068 BiLink* prev(void) const; void prev(BiLink*);
00069 BiLink* next(void) const; void next(BiLink*);
00070
00071 void add(BiLink*);
00072 void unlink(void);
00073
00074 void mark(void);
00075 bool marked(void) const;
00076
00077 bool empty(void) const;
00078 };
00079
00080 template <class View> class Edge;
00081
00091 template <class View>
00092 class Node : public BiLink {
00093 public:
00094 unsigned int pre, low, comp;
00095
00096 Node(void);
00097
00098 Edge<View>* edge_fst(void) const;
00099 Edge<View>* edge_lst(void) const;
00100
00101 static void* operator new(size_t, void*);
00102 };
00103
00108 template <class View>
00109 class ValNode : public Node<View> {
00110 protected:
00111 const int _val; Edge<View>* _matching;
00112 public:
00113 ValNode(int);
00114 int val(void) const;
00115 void matching(Edge<View>*);
00116 Edge<View>* matching(void) const;
00117 };
00118
00123 template <class View>
00124 class ViewNode : public Node<View> {
00125 protected:
00126 Edge<View>* _val_edges; View _view;
00127 public:
00128 ViewNode(View);
00129 Edge<View>* val_edges(void) const;
00130 Edge<View>** val_edges_ref(void);
00131
00132 View view(void) const;
00133 };
00134
00139 template <class View>
00140 class Edge : public BiLink {
00141 protected:
00142 Edge<View>* _next_edge;
00143 CombPtrFlag<Node<View> > sd;
00144 public:
00145 Edge(Node<View>*, Node<View>*);
00146
00147 Node<View>* dst(Node<View>*) const;
00148
00149 ViewNode<View>* view(ValNode<View>*) const;
00150 ValNode<View>* val(ViewNode<View>*) const;
00151
00152 bool used(Node<View>*) const;
00153 void use(void);
00154 void free(void);
00155
00156 void revert(Node<View>*);
00157
00158 Edge<View>* next_edge(void) const;
00159 Edge<View>** next_edge_ref(void);
00160
00161 Edge<View>* next(void) const;
00162 static void* operator new(size_t, void*);
00163 };
00164
00165 }}}
00166
00167 #include "gecode/int/distinct/combptr.icc"
00168 #include "gecode/int/distinct/bilink.icc"
00169 #include "gecode/int/distinct/node.icc"
00170 #include "gecode/int/distinct/edge.icc"
00171
00172 namespace Gecode { namespace Int { namespace Distinct {
00173
00178 template <class View>
00179 class DomCtrl<View>::ViewValGraph {
00180 protected:
00181 ViewNode<View>** view; int n_view;
00182 ValNode<View>** val; int n_val;
00183 char* mem;
00184 unsigned int count;
00185 unsigned int cnt0;
00186 unsigned int cnt1;
00187 Support::StaticStack<Node<View>*> n_s;
00188 public:
00189 ViewValGraph(int, View*, const int*, int, unsigned int);
00190 ViewValGraph(int, View*, int, unsigned int, int);
00191 ~ViewValGraph(void);
00192
00193 size_t size;
00194
00195 static ViewValGraph* init(int,View*);
00196
00197 bool initial_match(void);
00198
00199 void mark(void);
00200 void tell(Space*);
00201
00202 bool overflow(void) const;
00203
00204 bool sync(void);
00205
00206 protected:
00207 bool search_match(ViewNode<View>*);
00208 bool match(ViewNode<View>*);
00209 void scc(Node<View>*);
00210
00211 public:
00212
00213 static void* operator new(size_t);
00214 static void operator delete(void*);
00215 };
00216
00217
00218 template <class View>
00219 forceinline
00220 DomCtrl<View>::ViewValGraph::ViewValGraph(int n_view0, View* x,
00221 int n_val0,
00222 unsigned int n_edges, int min)
00223 : n_view(n_view0), n_val(n_val0),
00224 count(0), cnt0(0), cnt1(0), n_s(n_view+n_val)
00225 {
00226 size_t edge_size = sizeof(Edge<View>) * n_edges;
00227 size_t views_size = sizeof(ViewNode<View>) * n_view;
00228 size_t view_size = sizeof(ViewNode<View>*) * n_view;
00229 size_t vals_size = sizeof(ValNode<View>) * n_val;
00230 size_t val_size = sizeof(ValNode<View>*) * n_val;
00231 size_t size = edge_size +
00232 views_size + view_size + vals_size + val_size;
00233 mem = reinterpret_cast<char*>(Memory::malloc(size));
00234 Edge<View>* edges = reinterpret_cast<Edge<View>*>(mem);
00235 ViewNode<View>* view_nodes = reinterpret_cast<ViewNode<View>*>
00236 (mem+edge_size);
00237 ValNode<View>* val_nodes = reinterpret_cast<ValNode<View>*>
00238 (mem+edge_size+views_size);
00239 view = reinterpret_cast<ViewNode<View>**>
00240 (mem+edge_size+views_size+vals_size);
00241 val = reinterpret_cast<ValNode<View>**>
00242 (mem+edge_size+views_size+vals_size+view_size);
00243
00244
00245 {
00246 int v = min+n_val;
00247 for (int i = n_val; i--; )
00248 val[i] = new (val_nodes + i) ValNode<View>(--v);
00249 }
00250
00251
00252 for (int i = n_view; i--; ) {
00253 view[i] = new (view_nodes + i) ViewNode<View>(x[i]);
00254 Edge<View>** edge_p = view[i]->val_edges_ref();
00255 ViewValues<View> x_i(x[i]);
00256 while (x_i()) {
00257 *edge_p = new (edges++) Edge<View>(val_nodes+x_i.val()-min,
00258 view_nodes+i);
00259 edge_p = (*edge_p)->next_edge_ref();
00260 ++x_i;
00261 }
00262 *edge_p = NULL;
00263 }
00264 }
00265
00266 template <class View>
00267 forceinline
00268 DomCtrl<View>::ViewValGraph::ViewValGraph(int n_view0, View* x,
00269 const int* val_inf,
00270 int n_val0, unsigned int n_edges)
00271 : n_view(n_view0), n_val(n_val0),
00272 count(0), cnt0(0), cnt1(0), n_s(n_view+n_val)
00273 {
00274 size_t edge_size = sizeof(Edge<View>) * n_edges;
00275 size_t views_size = sizeof(ViewNode<View>) * n_view;
00276 size_t view_size = sizeof(ViewNode<View>*) * n_view;
00277 size_t vals_size = sizeof(ValNode<View>) * n_val;
00278 size_t val_size = sizeof(ValNode<View>*) * n_val;
00279 size_t size = edge_size +
00280 views_size + view_size + vals_size + val_size;
00281 mem = reinterpret_cast<char*>(Memory::malloc(size));
00282 Edge<View>* edges = reinterpret_cast<Edge<View>*>(mem);
00283 ViewNode<View>* view_nodes = reinterpret_cast<ViewNode<View>*>
00284 (mem+edge_size);
00285 ValNode<View>* val_nodes = reinterpret_cast<ValNode<View>*>
00286 (mem+edge_size+views_size);
00287 view = reinterpret_cast<ViewNode<View>**>
00288 (mem+edge_size+views_size+vals_size);
00289 val = reinterpret_cast<ValNode<View>**>
00290 (mem+edge_size+views_size+vals_size+view_size);
00291
00292
00293 for (int i = n_val; i--; )
00294 val[i] = new (val_nodes + i) ValNode<View>(val_inf[i]);
00295
00296
00297 for (int i = n_view; i--; ) {
00298 view[i] = new (view_nodes + i) ViewNode<View>(x[i]);
00299 Edge<View>** edge_p = view[i]->val_edges_ref();
00300 ViewValues<View> x_i(x[i]);
00301 int j = 0;
00302 while (x_i()) {
00303 while (val_inf[j] < x_i.val())
00304 j++;
00305 *edge_p = new (edges++) Edge<View>(val_nodes+j,view_nodes+i);
00306 edge_p = (*edge_p)->next_edge_ref();
00307 ++x_i;
00308 }
00309 *edge_p = NULL;
00310 }
00311 }
00312
00313 template <class View>
00314 typename DomCtrl<View>::ViewValGraph*
00315 DomCtrl<View>::ViewValGraph::init(int n_view, View* x) {
00316
00317 int min = x[n_view-1].min();
00318 int max = x[n_view-1].max();
00319 unsigned int size = x[n_view-1].size();
00320 for (int i=n_view-1; i--; ) {
00321 size += x[i].size();
00322 min = std::min(min,x[i].min());
00323 max = std::max(max,x[i].max());
00324 }
00325
00326 unsigned int width = max-min+1;
00327
00328
00329 if (width < static_cast<unsigned int>(n_view))
00330 return NULL;
00331
00332
00333 if (static_cast<unsigned int>(n_view)*2 >= width)
00334 return new ViewValGraph(n_view,x,static_cast<int>(width),size,min);
00335
00336 Support::DynamicArray<int> val_inf(64);
00337
00338 int n_val = 0;
00339 GECODE_AUTOARRAY(ViewRanges<View>,x_r,n_view);
00340 for (int i = n_view; i--; )
00341 x_r[i].init(x[i]);
00342 Iter::Ranges::NaryUnion<ViewRanges<View> > xu(x_r, n_view);
00343
00344 assert(xu());
00345
00346 do {
00347 for (int v = xu.min(); v <= xu.max(); v++)
00348 val_inf[n_val++] = v;
00349 ++xu;
00350 } while (xu());
00351 if (n_val < n_view)
00352 return NULL;
00353 return new ViewValGraph(n_view,x,val_inf,n_val,size);
00354 }
00355
00356 template <class View>
00357 bool
00358 DomCtrl<View>::ViewValGraph::search_match(ViewNode<View>* x) {
00359 x->comp = count;
00360
00361 {
00362 Edge<View>* e = x->val_edges();
00363
00364 assert(e != NULL);
00365 do {
00366 if (!e->val(x)->matching()) {
00367 e->revert(x); e->val(x)->matching(e);
00368 return true;
00369 }
00370 e = e->next_edge();
00371 } while (e != NULL);
00372 }
00373
00374 {
00375 Edge<View>* e = x->val_edges();
00376 do {
00377 ValNode<View>* n = e->val(x);
00378 ViewNode<View>* y = n->matching()->view(n);
00379 if ((y->comp < count) && search_match(y)) {
00380 n->matching()->revert(n);
00381 e->revert(x); n->matching(e);
00382 return true;
00383 }
00384 e = e->next_edge();
00385 } while (e != NULL);
00386 }
00387 return false;
00388 }
00389
00390 template <class View>
00391 forceinline bool
00392 DomCtrl<View>::ViewValGraph::match(ViewNode<View>* x) {
00393 assert(x->edge_fst() == x->edge_lst());
00394 count++;
00395 return search_match(x);
00396 }
00397
00398 template <class View>
00399 bool
00400 DomCtrl<View>::ViewValGraph::initial_match(void) {
00401 for (int i = n_view; i--; )
00402 if (!match(view[i]))
00403 return false;
00404 return true;
00405 }
00406
00407 template <class View>
00408 void
00409 DomCtrl<View>::ViewValGraph::scc(Node<View>* w) {
00410 w->pre = cnt0;
00411 w->low = cnt0;
00412 unsigned int min = cnt0++;
00413 n_s.push(w);
00414 for (Edge<View>* e = w->edge_fst(); e != w->edge_lst(); e = e->next()) {
00415 Node<View>* v = e->dst(w);
00416 if (v->pre < count)
00417 scc(v);
00418 if (v->low < min)
00419 min = v->low;
00420 }
00421 if (min < w->low) {
00422 w->low = min;
00423 return;
00424 }
00425 do {
00426 Node<View>* v = n_s.pop();
00427 v->comp = cnt1;
00428 v->low = UINT_MAX;
00429 } while (n_s.last() != w);
00430 cnt1++;
00431 }
00432
00433 template <class View>
00434 forceinline void
00435 DomCtrl<View>::ViewValGraph::mark(void) {
00436
00437
00438 n_s.reset();
00439
00440
00441 count++;
00442 for (int i = n_val; i--; )
00443 if (!val[i]->matching())
00444
00445 if (val[i]->empty()) {
00446 val[i] = val[--n_val];
00447 } else {
00448 val[i]->comp = count;
00449 n_s.push(val[i]);
00450 }
00451
00452
00453 while (!n_s.empty()) {
00454 ValNode<View>* n = static_cast<ValNode<View>*>(n_s.pop());
00455 for (Edge<View>* e = n->edge_fst(); e != n->edge_lst(); e = e->next()) {
00456
00457 e->use();
00458 ViewNode<View>* x = e->view(n);
00459 if (x->comp < count) {
00460 x->comp = count;
00461 assert(x->edge_fst()->next() == x->edge_lst());
00462 ValNode<View>* m = x->edge_fst()->val(x);
00463 x->edge_fst()->use();
00464 if (m->comp < count) {
00465 m->comp = count;
00466 n_s.push(m);
00467 }
00468 }
00469 }
00470 }
00471
00472 count++;
00473 cnt0 = count;
00474 cnt1 = count;
00475 n_s.reset();
00476 for (int i = n_view; i--; )
00477 if (view[i]->comp < count)
00478 scc(view[i]);
00479 count = cnt0+1;
00480 }
00481
00482 template <class View>
00483 forceinline void
00484 DomCtrl<View>::ViewValGraph::tell(Space* home) {
00485
00486 for (int i = n_view; i--; )
00487 if (!view[i]->edge_fst()->used(view[i])) {
00488 view[i]->view().eq(home,view[i]->edge_fst()->val(view[i])->val());
00489 view[i]->edge_fst()->val(view[i])->matching(NULL);
00490 view[i] = view[--n_view];
00491 } else {
00492 for (Edge<View>* e = view[i]->val_edges(); e!=NULL; e = e->next_edge())
00493 if (!e->used(view[i])) {
00494 view[i]->view().nq(home,e->val(view[i])->val());
00495 }
00496 }
00497 }
00498
00499 template <class View>
00500 forceinline bool
00501 DomCtrl<View>::ViewValGraph::overflow(void) const {
00502 return count > (UINT_MAX >> 1);
00503 }
00504
00505 template <class View>
00506 bool
00507 DomCtrl<View>::ViewValGraph::sync(void) {
00508
00509 GECODE_AUTOARRAY(ViewNode<View>*,re,n_view);
00510 int n_re = 0;
00511
00512 for (int i = n_view; i--; ) {
00513 ViewNode<View>* x = view[i];
00514 if (x->view().assigned()) {
00515 x->edge_fst()->val(x)->matching(NULL);
00516 for (Edge<View>* e = x->val_edges(); e != NULL; e = e->next_edge())
00517 e->unlink();
00518 view[i] = view[--n_view];
00519 } else {
00520 ViewRanges<View> r(x->view());
00521 Edge<View>* m = x->edge_fst();
00522 Edge<View>** p = x->val_edges_ref();
00523 Edge<View>* e = *p;
00524 do {
00525 while (e->val(x)->val() < r.min()) {
00526
00527 e->unlink(); e->mark();
00528 e = e->next_edge();
00529 *p = e;
00530 }
00531 assert(r.min() == e->val(x)->val());
00532
00533 for (unsigned int i=r.width(); i--; ) {
00534 e->free();
00535 p = e->next_edge_ref();
00536 e = e->next_edge();
00537 }
00538 ++r;
00539 } while (r());
00540 *p = NULL;
00541 while (e != NULL) {
00542 e->unlink(); e->mark();
00543 e = e->next_edge();
00544 }
00545 if (m->marked()) {
00546
00547 m->val(x)->matching(NULL);
00548 re[n_re++] = x;
00549 }
00550 }
00551 }
00552 while (n_re--)
00553 if (!match(re[n_re]))
00554 return false;
00555 return true;
00556 }
00557
00558 template <class View>
00559 forceinline
00560 DomCtrl<View>::ViewValGraph::~ViewValGraph(void) {
00561 Memory::free(mem);
00562 }
00563
00564 template <class View>
00565 forceinline void*
00566 DomCtrl<View>::ViewValGraph::operator new(size_t s) {
00567 return Memory::malloc(s);
00568 }
00569 template <class View>
00570 forceinline void
00571 DomCtrl<View>::ViewValGraph::operator delete(void* p) {
00572 Memory::free(p);
00573 }
00574
00575
00576
00577
00578
00579
00580 template <class View>
00581 forceinline
00582 DomCtrl<View>::DomCtrl(void) : vvg(NULL) {}
00583
00584 template <class View>
00585 forceinline bool
00586 DomCtrl<View>::available(void) {
00587 if ((vvg != NULL) && vvg->overflow()) {
00588 delete vvg;
00589 vvg = NULL;
00590 }
00591 return vvg != NULL;
00592 }
00593
00594 template <class View>
00595 forceinline ExecStatus
00596 DomCtrl<View>::init(int n, View* x) {
00597 assert(vvg == NULL);
00598 vvg = ViewValGraph::init(n,x);
00599 if ((vvg == NULL) || !vvg->initial_match())
00600 return ES_FAILED;
00601 return ES_OK;
00602 }
00603
00604 template <class View>
00605 forceinline ExecStatus
00606 DomCtrl<View>::sync(void) {
00607 return vvg->sync() ? ES_OK : ES_FAILED;
00608 }
00609
00610 template <class View>
00611 forceinline void
00612 DomCtrl<View>::propagate(Space* home) {
00613 vvg->mark();
00614 vvg->tell(home);
00615 }
00616
00617 template <class View>
00618 forceinline void
00619 DomCtrl<View>::flush(void) {
00620 delete vvg; vvg = NULL;
00621 }
00622
00623 template <class View>
00624 forceinline size_t
00625 DomCtrl<View>::size(void) const {
00626 return (vvg != NULL) ? vvg->size : 0;
00627 }
00628
00629 template <class View>
00630 forceinline void
00631 DomCtrl<View>::dispose(void) {
00632 delete vvg;
00633 }
00634
00635
00636
00637
00638
00639
00640
00641
00642 template <class View>
00643 forceinline
00644 Dom<View>::Dom(Space* home, ViewArray<View>& x)
00645 : NaryPropagator<View,PC_INT_DOM>(home,x,true) {}
00646
00647 template <class View>
00648 ExecStatus
00649 Dom<View>::post(Space* home, ViewArray<View>& x) {
00650 if (x.size() == 2)
00651 return Rel::Nq<View>::post(home,x[0],x[1]);
00652 if (x.size() == 3)
00653 return TerDom<View>::post(home,x[0],x[1],x[2]);
00654 if (x.size() > 3) {
00655
00656 if (prop_bnd<View>(home,x,x.size()) == ES_FAILED)
00657 return ES_FAILED;
00658 (void) new (home) Dom<View>(home,x);
00659 }
00660 return ES_OK;
00661 }
00662
00663 template <class View>
00664 forceinline
00665 Dom<View>::Dom(Space* home, bool share, Dom<View>& p)
00666 : NaryPropagator<View,PC_INT_DOM>(home,share,p) {}
00667
00668 template <class View>
00669 void
00670 Dom<View>::flush(void) {
00671 dc.flush();
00672 }
00673
00674 template <class View>
00675 size_t
00676 Dom<View>::size(void) const {
00677 return dc.size();
00678 }
00679
00680 template <class View>
00681 PropCost
00682 Dom<View>::cost(void) const {
00683 return cost_lo(x.size(),
00684 (View::pme(this) == ME_INT_VAL)
00685 ? PC_LINEAR_LO : PC_CUBIC_LO);
00686 }
00687
00688 template <class View>
00689 Actor*
00690 Dom<View>::copy(Space* home, bool share) {
00691 return new (home) Dom<View>(home,share,*this);
00692 }
00693
00694 template <class View>
00695 ExecStatus
00696 Dom<View>::propagate(Space* home) {
00697 if (View::pme(this) == ME_INT_VAL) {
00698 ExecStatus es = prop_val<View,false>(home,x);
00699 if ((es == ES_FAILED) || (es == ES_SUBSUMED))
00700 return es;
00701 if (es == ES_FIX)
00702 return this->ES_FIX_PARTIAL(View::pme(ME_INT_DOM));
00703 if (prop_bnd<View>(home,x,x.size()) == ES_FAILED)
00704 return ES_FAILED;
00705 es = prop_val<View,true>(home,x);
00706 if ((es == ES_FAILED) || (es == ES_SUBSUMED))
00707 return es;
00708 return this->ES_FIX_PARTIAL(View::pme(ME_INT_DOM));
00709 }
00710
00711 if (x.size() == 2) {
00712 GECODE_ES_CHECK(Rel::Nq<View>::post(home,x[0],x[1]));
00713 return ES_SUBSUMED;
00714 }
00715 if (x.size() == 3) {
00716 GECODE_ES_CHECK(TerDom<View>::post(home,x[0],x[1],x[2]));
00717 return ES_SUBSUMED;
00718 }
00719
00720 if (dc.available()) {
00721 GECODE_ES_CHECK(dc.sync());
00722 } else {
00723 GECODE_ES_CHECK(dc.init(x.size(),&x[0]));
00724 }
00725 dc.propagate(home);
00726 return ES_FIX;
00727 }
00728
00729 template <class View>
00730 size_t
00731 Dom<View>::dispose(Space* home) {
00732 dc.dispose();
00733 (void) NaryPropagator<View,PC_INT_DOM>::dispose(home);
00734 return sizeof(*this);
00735 }
00736
00737 }}}
00738
00739
00740