integerset.cc
Go to the documentation of this file.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
00040 #include "gecode/set.hh"
00041
00042 namespace Gecode { namespace Set {
00043
00044 BndSet::BndSet(Space* home, const IntSet& is) {
00045 if (is.size()==0) {
00046 fst(NULL); lst(NULL); _size = 0;
00047 } else {
00048 int n = is.size();
00049 RangeList* r =
00050 static_cast<RangeList*>(home->alloc(sizeof(RangeList)*n));
00051 fst(r); lst(r+n-1);
00052 unsigned int s = 0;
00053 for (int i = n; i--; ) {
00054 s += is.width(i);
00055 r[i].min(is.min(i)); r[i].max(is.max(i));
00056 r[i].next(&r[i+1]);
00057 }
00058 r[n-1].next(NULL);
00059 _size = s;
00060 }
00061 assert(isConsistent());
00062 }
00063
00064 bool
00065 GLBndSet::include_full(Space* home, int mi, int ma, SetDelta& d) {
00066 assert(ma >= mi);
00067 assert(fst() != NULL);
00068
00069 RangeList* p = NULL;
00070 RangeList* c = fst();
00071
00072 while (c != NULL) {
00073 if (c->max() >= mi-1){
00074 if (c->min() > ma+1) {
00075 _size+=(ma-mi+1);
00076 d._glbMin = mi;
00077 d._glbMax = ma;
00078 RangeList* q=new (home) RangeList(mi,ma,c);
00079 if (p==NULL)
00080
00081 fst(q);
00082 else
00083 p->next(q);
00084 return true;
00085 }
00086
00087 bool result = false;
00088 if (c->min()>mi) {
00089 _size+=(c->min()-mi);
00090 c->min(mi);
00091 d._glbMin = mi;
00092 result = true;
00093 } else {
00094 d._glbMin = c->max()+1;
00095 }
00096 assert(c->min()<=mi);
00097 assert(c->max()+1>=mi);
00098 if (c->max() >= ma) {
00099 d._glbMax = c->min()-1;
00100 return result;
00101 }
00102 RangeList* q = c;
00103
00104 int prevMax = c->max();
00105 int growth = 0;
00106
00107 while (q->next() != NULL && q->next()->min() <= ma+1) {
00108 q = q->next();
00109 growth += q->min()-prevMax-1;
00110 prevMax = q->max();
00111 }
00112 assert(growth>=0);
00113 _size+=growth;
00114 if (q->max() < ma) {
00115 _size += ma-q->max();
00116 d._glbMax = ma;
00117 } else {
00118 d._glbMax = q->min()-1;
00119 }
00120 c->max(std::max(ma,q->max()));
00121 if (c!=q) {
00122 RangeList* oldCNext = c->next();
00123 assert(oldCNext!=NULL);
00124 c->next(q->next());
00125 if (q->next()==NULL){
00126 assert(q==lst());
00127 lst(c);
00128 }
00129 oldCNext->dispose(home,q);
00130 }
00131 return true;
00132 }
00133 RangeList* nc = c->next();
00134 p=c; c=nc;
00135 }
00136
00137 assert(mi>max()+1);
00138 RangeList* q = new (home) RangeList(mi, ma, NULL);
00139 lst()->next(q);
00140 lst(q);
00141 _size+= q->width();
00142 d._glbMin = mi;
00143 d._glbMax = ma;
00144 return true;
00145 }
00146
00147 bool
00148 LUBndSet::intersect_full(Space* home, int mi, int ma) {
00149 RangeList* p = NULL;
00150 RangeList* c = fst();
00151
00152 assert(c != NULL);
00153
00154
00155 while (c != NULL && c->max() < mi) {
00156 _size -= c->width();
00157 RangeList *nc = c->next();
00158 p=c; c=nc;
00159 }
00160 if (c == NULL) {
00161
00162 fst()->dispose(home, lst());
00163 fst(NULL); lst(NULL);
00164 return true;
00165 }
00166
00167 bool changed = false;
00168 if (c != fst()) {
00169 fst()->dispose(home, p);
00170 fst(c);
00171 p = NULL;
00172 changed = true;
00173 }
00174
00175 if (mi > c->min()) {
00176 _size -= mi-c->min();
00177 c->min(mi);
00178 changed = true;
00179 }
00180
00181 while (c != NULL && c->max() <= ma) {
00182 RangeList *nc = c->next();
00183 p=c; c=nc;
00184 }
00185
00186 if (c == NULL)
00187 return changed;
00188
00189 RangeList* newlst = p;
00190 if (ma >= c->min()) {
00191 _size -= c->max() - ma;
00192 c->max(ma);
00193 newlst = c;
00194 RangeList* nc = c->next();
00195 c->next(NULL);
00196 p=c; c=nc;
00197 } else if (p != NULL) {
00198 p->next(NULL);
00199 }
00200 if (c != NULL) {
00201 for (RangeList* cc = c ; cc != NULL; cc = cc->next())
00202 _size -= cc->width();
00203 c->dispose(home, lst());
00204 }
00205 lst(newlst);
00206 if (newlst==NULL)
00207 fst(NULL);
00208 return true;
00209 }
00210
00211 bool
00212 LUBndSet::exclude_full(Space* home, int mi, int ma, SetDelta& d) {
00213 assert(ma >= mi);
00214 assert(mi <= max() && ma >= min() &&
00215 (mi > min() || ma < max()));
00216 bool result=false;
00217
00218 RangeList* p = NULL;
00219 RangeList* c = fst();
00220 d._lubMin = Limits::max+1;
00221 while (c != NULL) {
00222 if (c->max() >= mi){
00223 if (c->min() > ma) { return result; }
00224
00225 if (c->min()<mi && c->max() > ma) {
00226 RangeList* q =
00227 new (home) RangeList(ma+1,c->max(),c->next());
00228 c->max(mi-1);
00229 if (c == lst()) {
00230 lst(q);
00231 }
00232 c->next(q);
00233 _size -= (ma-mi+1);
00234 d._lubMin = mi;
00235 d._lubMax = ma;
00236 return true;
00237 }
00238
00239 if (c->max() > ma) {
00240 d._lubMin = std::min(d._lubMin, c->min());
00241 d._lubMax = ma;
00242 _size-=(ma-c->min()+1);
00243 c->min(ma+1);
00244 return true;
00245 }
00246
00247 if (c->min() < mi) {
00248 _size-=(c->max()-mi+1);
00249 d._lubMin = mi;
00250 d._lubMax = c->max();
00251 c->max(mi-1);
00252 result=true;
00253 } else {
00254 d._lubMin = c->min();
00255 _size-=c->width();
00256 RangeList *cend = c;
00257 while ((cend->next()!=NULL) && (cend->next()->max()<=ma)){
00258 cend = cend->next();
00259 _size-=cend->width();
00260 }
00261 d._lubMax = cend->max();
00262 if (fst()==c) {
00263 fst(cend->next());
00264 } else {
00265 p->next(cend->next());
00266 }
00267 if (lst()==cend) {
00268 lst(p);
00269 }
00270 RangeList* nc=cend->next();
00271 c->dispose(home,cend);
00272 p=cend;
00273 c=nc;
00274 if (c != NULL && c->min() <= ma ) {
00275
00276 _size-=(ma-c->min()+1);
00277 c->min(ma+1);
00278 d._lubMax = ma;
00279 }
00280 return true;
00281 }
00282 }
00283 RangeList *nc = c->next();
00284 p=c; c=nc;
00285 }
00286 return result;
00287 }
00288
00289 #ifndef NDEBUG
00290 using namespace Gecode::Int;
00291 #endif
00292
00293 bool
00294 BndSet::isConsistent(void) const {
00295 #ifndef NDEBUG
00296 if (fst()==NULL) {
00297 if (lst()!=NULL || size()!=0) {
00298 std::cerr<<"Strange empty set.\n";
00299 return false;
00300 } else return true;
00301 }
00302
00303 if (fst()!=NULL && lst()==NULL) {
00304 std::cerr<<"First is not null, last is.\n";
00305 return false;
00306 }
00307
00308 RangeList *p=NULL;
00309 RangeList *c=fst();
00310
00311 int min = c->min();
00312 int max = c->max();
00313
00314 if (max<min) {
00315 std::cerr << "Single range list twisted: ("<<min<<","<<max<<")" ;
00316 return false;
00317 }
00318
00319 RangeList *nc=c->next();
00320 p=c; c=nc;
00321 while (c) {
00322 if (max<min) {
00323 std::cerr << "1";
00324 return false;
00325 }
00326 if ((max+1)>=c->min()) {
00327 std::cerr << "2";
00328 return false;
00329 }
00330 if (c->next()==NULL && c!=lst()) {
00331 std::cerr << "3";
00332 return false;
00333 }
00334
00335 min = c->min();
00336 max = c->max();
00337
00338 nc=c->next();
00339 p=c; c=nc;
00340 }
00341 #endif
00342 return true;
00343 }
00344
00345
00346 }}
00347
00348
00349