Generated on Wed Nov 1 15:04:47 2006 for Gecode by doxygen 1.4.5

integerset.icc

Go to the documentation of this file.
00001 /*
00002  *  Main authors:
00003  *     Guido Tack <tack@gecode.org>
00004  *     Gabor Szokoli <szokoli@gecode.org>
00005  *     Christian Schulte <schulte@gecode.org>
00006  *
00007  *  Copyright:
00008  *     Guido Tack, 2004
00009  *     Christian Schulte, 2004
00010  *     Gabor Szokoli, 2004
00011  *
00012  *  Last modified:
00013  *     $Date: 2006-07-19 14:57:38 +0200 (Wed, 19 Jul 2006) $ by $Author: schulte $
00014  *     $Revision: 3413 $
00015  *
00016  *  This file is part of Gecode, the generic constraint
00017  *  development environment:
00018  *     http://www.gecode.org
00019  *
00020  *  See the file "LICENSE" for information on usage and
00021  *  redistribution of this file, and for a
00022  *     DISCLAIMER OF ALL WARRANTIES.
00023  *
00024  */
00025 
00026 namespace Gecode { namespace Set {
00027 
00028   /*
00029    * Range lists
00030    *
00031    */
00032 
00033 #define GECODE_SET_RL2PD(r) reinterpret_cast<ptrdiff_t>(r)
00034 #define GECODE_SET_PD2RL(p) reinterpret_cast<RangeList*>(p)
00035 
00036   forceinline
00037   RangeList::RangeList(void) {}
00038 
00039   forceinline
00040   RangeList::RangeList(int min, int max, RangeList* p, RangeList* n)
00041     : _min(min), _max(max) {
00042     _next = GECODE_SET_PD2RL(GECODE_SET_RL2PD(p)^GECODE_SET_RL2PD(n));     
00043   }
00044 
00045   forceinline RangeList*
00046   RangeList::next(const RangeList* p) const {
00047     return GECODE_SET_PD2RL(GECODE_SET_RL2PD(_next)^GECODE_SET_RL2PD(p));
00048   }
00049   forceinline RangeList*
00050   RangeList::prev(const RangeList* n) const {
00051     return GECODE_SET_PD2RL(GECODE_SET_RL2PD(_next)^GECODE_SET_RL2PD(n));
00052   }
00053   forceinline void
00054   RangeList::prevnext(RangeList* p, RangeList* n) {
00055     _next = GECODE_SET_PD2RL(GECODE_SET_RL2PD(p)^GECODE_SET_RL2PD(n));
00056   }
00057   forceinline void
00058   RangeList::next(RangeList* o, RangeList* n) {
00059     _next = GECODE_SET_PD2RL(GECODE_SET_RL2PD(_next)^
00060                              (GECODE_SET_RL2PD(o)^GECODE_SET_RL2PD(n)));
00061   }
00062   forceinline void
00063   RangeList::prev(RangeList* o, RangeList* n) {
00064     _next = GECODE_SET_PD2RL(GECODE_SET_RL2PD(_next)^
00065                              (GECODE_SET_RL2PD(o)^GECODE_SET_RL2PD(n)));
00066   }
00067   forceinline void
00068   RangeList::fix(RangeList* n) {
00069     _next = n;
00070   }
00071 
00072   forceinline void
00073   RangeList::min(int n) {
00074     _min = n;
00075   }
00076   forceinline void
00077   RangeList::max(int n) {
00078     _max = n;
00079   }
00080 
00081   forceinline int
00082   RangeList::min(void) const {
00083     return _min;
00084   }
00085   forceinline int
00086   RangeList::max(void) const {
00087     return _max;
00088   }
00089   forceinline unsigned int
00090   RangeList::width(void) const {
00091     return _max - _min + 1;
00092   }
00093 
00094 
00095   forceinline void
00096   RangeList::operator delete(void*) {}
00097 
00098   forceinline void
00099   RangeList::operator delete(void*, Space* home) {
00100     GECODE_NEVER;
00101   }
00102 
00103   forceinline void*
00104   RangeList::operator new(size_t s, Space* home) {
00105     assert(s == sizeof(RangeList));
00106     return home->fl_alloc<sizeof(RangeList)>();
00107   }
00108 
00109   forceinline void
00110   RangeList::dispose(Space* home, RangeList* p, RangeList* l) {
00111     RangeList* c = this;
00112     while (c != l) {
00113       RangeList* n = c->next(p);
00114       c->fix(n);
00115       p=c; c=n;
00116     }
00117     home->fl_dispose<sizeof(RangeList)>(this,l);
00118   }
00119 
00120 #undef GECODE_SET_RL2PD
00121 #undef GECODE_SET_PD2RL
00122 
00123 
00124   /*
00125    * BndSet
00126    *
00127    */
00128 
00129   forceinline
00130   BndSet::BndSet(void) :
00131     first(NULL), last(NULL), _size(0) {}
00132 
00133   forceinline RangeList*
00134   BndSet::fst(void) const {
00135     return first;
00136   }
00137 
00138   forceinline RangeList*
00139   BndSet::lst(void) const {
00140     return last;
00141   }
00142 
00143   forceinline void
00144   BndSet::dispose(Space* home) {
00145     if (fst()!=NULL)
00146       fst()->dispose(home,NULL,lst());
00147   }
00148 
00149   forceinline void
00150   BndSet::fst(RangeList* f) {
00151     first = f;
00152   }
00153 
00154   forceinline void
00155   BndSet::lst(RangeList* l) {
00156     last = l;
00157   }
00158 
00159   forceinline
00160   BndSet::BndSet(Space* home, int mn, int mx) {
00161     RangeList* p = 
00162       new (home) RangeList(mn,mx,NULL,NULL);
00163     fst(p); lst(p);
00164     _size = mx-mn+1;
00165   }
00166 
00167   forceinline RangeList*
00168   BndSet::ranges(void) const {
00169     return fst();
00170   }
00171 
00172   forceinline unsigned int
00173   BndSet::size(void) const {
00174     return _size;
00175   }
00176 
00177   forceinline bool
00178   BndSet::empty(void) const {
00179     return (_size==0);
00180   }
00181 
00182   forceinline int
00183   BndSet::min(void) const {
00184     if (fst()==NULL) { return MIN_OF_EMPTY; }
00185     else { return fst()->min(); }
00186   }
00187 
00188   forceinline int
00189   BndSet::max(void) const {
00190     if (lst()==NULL) { return MAX_OF_EMPTY; }
00191     else { return lst()->max(); }
00192   }
00193 
00194   // nth smallest element
00195   forceinline int
00196   BndSet::minN(unsigned int n) const {
00197     RangeList* p=NULL;
00198     RangeList* c=fst();
00199     while (c!=NULL){
00200       if (c->width() > n){
00201         return(c->min()+n);
00202       } else {
00203         n-=c->width();
00204         RangeList* nc=c->next(p);
00205         p=c; c=nc;
00206       }
00207     }
00208     return MIN_OF_EMPTY;
00209   }
00210 
00211   // nth largest element
00212   forceinline int
00213   BndSet::maxN(unsigned int n) const {
00214     RangeList* p=NULL;
00215     RangeList* c=lst();
00216     while (c!=NULL){
00217       if (c->width() > n){
00218         return(c->max()-n);
00219       } else {
00220         n-=c->width();
00221         RangeList* nc=c->next(p);
00222         p=c; c=nc;
00223       }
00224     }
00225     return MAX_OF_EMPTY;
00226   }
00227 
00228   forceinline void
00229   BndSet::update(Space* home, BndSet& d) {
00230     if ( d.fst() == fst()) { return; }
00231     if (fst()!=NULL) { fst()->dispose(home,NULL,lst()); }
00232     _size = d.size();
00233     if (_size==0) { fst(NULL); lst(NULL); return ; }
00234 
00235     int n=0;
00236     {
00237       RangeList* p = NULL;
00238       RangeList* c = d.fst();
00239       while (c!=NULL) {
00240         RangeList* nc=c->next(p);
00241         p=c; c=nc; n++;
00242       }
00243     }
00244 
00245     RangeList* r = reinterpret_cast<RangeList*>
00246       (home->alloc(sizeof(RangeList)*n));
00247     fst(r); lst(r+n-1);
00248 
00249     {
00250       RangeList* p = NULL;
00251       RangeList* c = d.lst();
00252       for (int i=n; i--; ) {
00253         r[i].min(c->min());
00254         r[i].max(c->max());
00255         r[i].prevnext(&r[i-1],&r[i+1]);
00256 
00257         RangeList* nc=c->next(p);
00258         p=c; c=nc;
00259       }
00260       r[0].prev(&r[-1],NULL); 
00261       r[n-1].next(&r[n],NULL);
00262     }
00263 
00264   }
00265 
00266   template <class I> forceinline bool
00267   BndSet::overwrite(Space* home, I& ri) {
00268     // Is new domain empty?
00269     if (!ri()) {
00270       //Was it empty?
00271       if (fst()==NULL)
00272         return false;
00273       fst()->dispose(home,NULL,lst());
00274       _size=0; fst(NULL); lst(NULL);
00275       return true;
00276     }
00277 
00278     RangeList* f =
00279       new (home) RangeList(ri.min(),ri.max(),NULL,NULL);
00280     RangeList* l = f;
00281     unsigned int s = ri.width();
00282 
00283     ++ri;
00284     
00285     while (ri()){
00286       RangeList *n = new (home) RangeList(ri.min(),ri.max(),l,NULL);
00287       l->next(NULL,n);
00288       l=n;
00289       s += ri.width();
00290       ++ri;
00291     }
00292 
00293     if (fst() != NULL)
00294       fst()->dispose(home,NULL,lst());
00295     fst(f); lst(l);
00296 
00297     // If the size did not change, nothing changed, as overwriting
00298     // must not at the same time include and exclude elements.
00299     if (size() == s)
00300       return false;
00301 
00302     _size = s;
00303     return true;
00304   }
00305 
00306   forceinline void
00307   BndSet::linkTo(Space* home, const BndSet& that){
00308     if (fst()!=NULL){
00309       assert(lst()!=NULL);
00310       assert(fst()!= that.fst());
00311       fst()->dispose(home,NULL,lst());
00312     }
00313     fst(that.fst());
00314     lst(that.lst());
00315     _size = that.size();
00316     assert(isConsistent());
00317   }
00318 
00319   forceinline bool
00320   BndSet::in(int i) const {
00321     RangeList *p = NULL;
00322     RangeList *c = fst();
00323     while (c) {
00324       if (c->min() <= i && c->max() >= i)
00325         return true;
00326       if (c->min() > i)
00327         return false;
00328       RangeList* nc = c->next(p);
00329       p=c; c=nc;
00330     }
00331     return false;
00332   }
00333 
00334   /*
00335    * Forward range iterator for BndSets
00336    *
00337    */
00338 
00339   forceinline
00340   BndSetRanges::BndSetRanges(void) {}
00341 
00342   forceinline
00343   BndSetRanges::BndSetRanges(const BndSet& s) :
00344     p(NULL), c(s.ranges()) {}
00345 
00346   forceinline void
00347   BndSetRanges::init(const BndSet& s) {
00348     p = NULL;
00349     c = s.ranges();
00350   }
00351 
00352   forceinline bool
00353   BndSetRanges::operator()(void) const {
00354     return c != NULL;
00355   }
00356   forceinline void
00357   BndSetRanges::operator++(void) {
00358     const RangeList* n=c->next(p); p=c; c=n;
00359   }
00360 
00361   forceinline int
00362   BndSetRanges::min(void) const {
00363     return c->min();
00364   }
00365   forceinline int
00366   BndSetRanges::max(void) const {
00367     return c->max();
00368   }
00369   forceinline unsigned int
00370   BndSetRanges::width(void) const {
00371     return c->width();
00372   }
00373 
00374   /*
00375    * GLBndSet
00376    *
00377    */
00378 
00379   forceinline
00380   GLBndSet::GLBndSet(Space* home) {}
00381 
00382   forceinline
00383   GLBndSet::GLBndSet(Space* home, int mi, int ma)
00384     : BndSet(home,mi,ma) { assert(mi<=ma); }
00385 
00386   forceinline
00387   GLBndSet::GLBndSet(Space* home, const IntSet& s)
00388     : BndSet(home,s) {}
00389 
00390   forceinline void
00391   GLBndSet::init(Space* home) { fst(NULL); lst(NULL); _size = 0; }
00392 
00393   forceinline bool
00394   GLBndSet::include(Space* home, int mi, int ma) {
00395     assert(ma >= mi);
00396     if (fst()==NULL) {
00397       RangeList* p = new (home) RangeList(mi,ma,NULL,NULL);
00398       fst(p);
00399       lst(p);
00400       _size=ma-mi+1;
00401       return true;
00402     }
00403     bool ret = include_full(home, mi, ma);
00404     assert(isConsistent());
00405     return ret;
00406   }
00407 
00408   template <class I> bool
00409   GLBndSet::includeI(Space* home, I& i) {
00410     if (!i())
00411       return false;
00412     BndSetRanges j(*this);
00413     Iter::Ranges::Union<BndSetRanges,I> ij(j,i);
00414     bool me = overwrite(home, ij);
00415     assert(isConsistent());
00416     return me;
00417   }
00418 
00419 
00420   /*
00421    * LUBndSet
00422    *
00423    */
00424 
00425   forceinline
00426   LUBndSet::LUBndSet(void) {}
00427 
00428   forceinline
00429   LUBndSet::LUBndSet(Space* home)
00430     : BndSet(home,Limits::Set::int_min,Limits::Set::int_max) {}
00431 
00432   forceinline
00433   LUBndSet::LUBndSet(Space* home, int mi, int ma)
00434     : BndSet(home,mi,ma) { assert(mi<=ma); }
00435 
00436   forceinline
00437   LUBndSet::LUBndSet(Space* home, const IntSet& s)
00438     : BndSet(home,s) {}
00439 
00440   forceinline void
00441   LUBndSet::init(Space* home) {
00442     RangeList *p =
00443       new (home) RangeList(Limits::Set::int_min,
00444                            Limits::Set::int_max,
00445                            NULL,NULL);
00446     fst(p);
00447     lst(p);
00448     _size = Limits::Set::card_max;
00449   }
00450 
00451   forceinline bool
00452   LUBndSet::exclude(Space* home, int mi, int ma) {
00453     assert(ma >= mi);
00454     if ((mi > max()) || (ma < min())) { return false; }
00455     if (mi <= min() && ma >= max() ) { //the range covers the whole set
00456       fst()->dispose(home,NULL,lst()); fst(NULL); lst(NULL);
00457       _size=0;
00458       return true;
00459     }
00460     bool ret =  exclude_full(home, mi, ma);
00461     assert(isConsistent());
00462     return ret;
00463   }
00464 
00465   template <class I> bool
00466   LUBndSet::intersectI(Space* home, I& i) {
00467     if (fst()==NULL) { return false; }
00468     if (!i()) {
00469       fst()->dispose(home,NULL,lst()); fst(NULL); lst(NULL);
00470       _size=0;
00471       return true;
00472     }
00473     BndSetRanges j(*this);
00474     Iter::Ranges::Inter<BndSetRanges,I> ij(j,i);
00475     bool ret = overwrite(home, ij);
00476     assert(isConsistent());
00477     return ret;
00478   }
00479 
00480   template <class I> bool
00481   LUBndSet::excludeI(Space* home, I& i) {
00482     if (!i()) { return false; }
00483     BndSetRanges j(*this);
00484     Iter::Ranges::Diff<BndSetRanges,I> ij(j,i);
00485     bool ret = overwrite(home, ij);
00486     assert(isConsistent());
00487     return ret;
00488   }
00489 
00490   /*
00491    * A complement iterator spezialized for the BndSet limits
00492    *
00493    */
00494   template <class I>
00495   RangesCompl<I>::RangesCompl(void) {}
00496 
00497   template <class I>
00498   RangesCompl<I>::RangesCompl(I& i)
00499     : Iter::Ranges::Compl<Limits::Set::int_min,
00500                           Limits::Set::int_max,
00501                           I>(i) {}
00502 
00503   template <class I> void
00504   RangesCompl<I>::init(I& i) {
00505     Iter::Ranges::Compl<Limits::Set::int_min,
00506       Limits::Set::int_max,I>::init(i);
00507   }
00508 
00509 }}
00510 
00511 // STATISTICS: set-var
00512