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 #include "gecode/int.hh"
00039
00040 namespace Gecode { namespace Int {
00041
00042 forceinline bool
00043 IntVarImp::closer_min(int n) const {
00044 unsigned int l = static_cast<unsigned int>(n - dom.min());
00045 unsigned int r = static_cast<unsigned int>(dom.max() - n);
00046 return l < r;
00047 }
00048
00049 int
00050 IntVarImp::med(void) const {
00051
00052 if (fst() == NULL)
00053 return (dom.min()+dom.max())/2;
00054 unsigned int i = size() / 2;
00055 const RangeList* p = NULL;
00056 const RangeList* c = fst();
00057 while (i >= c->width()) {
00058 i -= c->width();
00059 const RangeList* n=c->next(p); p=c; c=n;
00060 }
00061 return c->min() + static_cast<int>(i);
00062 }
00063
00064 bool
00065 IntVarImp::in_full(int m) const {
00066 if (closer_min(m)) {
00067 const RangeList* p = NULL;
00068 const RangeList* c = fst();
00069 while (m > c->max()) {
00070 const RangeList* n=c->next(p); p=c; c=n;
00071 }
00072 return (m >= c->min());
00073 } else {
00074 const RangeList* n = NULL;
00075 const RangeList* c = lst();
00076 while (m < c->min()) {
00077 const RangeList* p=c->prev(n); n=c; c=p;
00078 }
00079 return (m <= c->max());
00080 }
00081 }
00082
00083
00084
00085
00086
00087
00088 ModEvent
00089 IntVarImp::lq_full(Space* home, int m) {
00090 assert((m >= dom.min()) && (m <= dom.max()));
00091 IntDelta d(m+1,dom.max());
00092 ModEvent me = ME_INT_BND;
00093 if (range()) {
00094 dom.max(m);
00095 if (assigned()) me = ME_INT_VAL;
00096 } else if (m < fst()->next(NULL)->min()) {
00097 dom.max(std::min(m,fst()->max()));
00098 fst()->dispose(home,NULL,lst());
00099 fst(NULL); holes = 0;
00100 if (assigned()) me = ME_INT_VAL;
00101 } else {
00102 RangeList* n = NULL;
00103 RangeList* c = lst();
00104 unsigned int h = 0;
00105 while (m < c->min()) {
00106 RangeList* p = c->prev(n); c->fix(n);
00107 h += (c->min() - p->max() - 1);
00108 n=c; c=p;
00109 }
00110 holes -= h;
00111 int max_c = std::min(m,c->max());
00112 dom.max(max_c); c->max(max_c);
00113 if (c != lst()) {
00114 lst()->dispose(home,n);
00115 c->next(n,NULL); lst(c);
00116 }
00117 }
00118 return notify(home,me,&d);
00119 }
00120
00121 ModEvent
00122 IntVarImp::gq_full(Space* home, int m) {
00123 assert((m >= dom.min()) && (m <= dom.max()));
00124 IntDelta d(dom.min(),m-1);
00125 ModEvent me = ME_INT_BND;
00126 if (range()) {
00127 dom.min(m);
00128 if (assigned()) me = ME_INT_VAL;
00129 } else if (m > lst()->prev(NULL)->max()) {
00130 dom.min(std::max(m,lst()->min()));
00131 fst()->dispose(home,NULL,lst());
00132 fst(NULL); holes = 0;
00133 if (assigned()) me = ME_INT_VAL;
00134 } else {
00135 RangeList* p = NULL;
00136 RangeList* c = fst();
00137 unsigned int h = 0;
00138 while (m > c->max()) {
00139 RangeList* n = c->next(p); c->fix(n);
00140 h += (n->min() - c->max() - 1);
00141 p=c; c=n;
00142 }
00143 holes -= h;
00144 int min_c = std::max(m,c->min());
00145 dom.min(min_c); c->min(min_c);
00146 if (c != fst()) {
00147 fst()->dispose(home,p);
00148 c->prev(p,NULL); fst(c);
00149 }
00150 }
00151 return notify(home,me,&d);
00152 }
00153
00154 ModEvent
00155 IntVarImp::eq_full(Space* home, int m) {
00156 dom.min(m); dom.max(m);
00157 if (!range()) {
00158 bool failed = false;
00159 RangeList* p = NULL;
00160 RangeList* c = fst();
00161 while (m > c->max()) {
00162 RangeList* n=c->next(p); c->fix(n); p=c; c=n;
00163 }
00164 if (m < c->min())
00165 failed = true;
00166 while (c != NULL) {
00167 RangeList* n=c->next(p); c->fix(n); p=c; c=n;
00168 }
00169 assert(p == lst());
00170 fst()->dispose(home,p);
00171 fst(NULL); holes = 0;
00172 if (failed)
00173 return ME_INT_FAILED;
00174 }
00175 IntDelta d;
00176 return notify(home,ME_INT_VAL,&d);
00177 }
00178
00179 ModEvent
00180 IntVarImp::nq_full(Space* home, int m) {
00181 assert(!((m < dom.min()) || (m > dom.max())));
00182 ModEvent me = ME_INT_DOM;
00183 if (range()) {
00184 if ((m == dom.min()) && (m == dom.max()))
00185 return ME_INT_FAILED;
00186 if (m == dom.min()) {
00187 dom.min(m+1);
00188 me = assigned() ? ME_INT_VAL : ME_INT_BND;
00189 } else if (m == dom.max()) {
00190 dom.max(m-1);
00191 me = assigned() ? ME_INT_VAL : ME_INT_BND;
00192 } else {
00193 RangeList* f = new (home) RangeList(dom.min(),m-1);
00194 RangeList* l = new (home) RangeList(m+1,dom.max());
00195 f->prevnext(NULL,l);
00196 l->prevnext(f,NULL);
00197 fst(f); lst(l); holes = 1;
00198 }
00199 } else if (m < fst()->next(NULL)->min()) {
00200 int f_max = fst()->max();
00201 if (m > f_max)
00202 return ME_INT_NONE;
00203 int f_min = dom.min();
00204 if ((m == f_min) && (m == f_max)) {
00205 RangeList* f_next = fst()->next(NULL);
00206 dom.min(f_next->min());
00207 if (f_next == lst()) {
00208
00209 fst()->dispose(home,f_next);
00210 fst(NULL); holes = 0;
00211 me = assigned() ? ME_INT_VAL : ME_INT_BND;
00212 } else {
00213 f_next->prev(fst(),NULL);
00214 fst()->dispose(home); fst(f_next);
00215 holes -= dom.min() - f_min - 1;
00216 me = ME_INT_BND;
00217 }
00218 } else if (m == f_min) {
00219 dom.min(m+1); fst()->min(m+1);
00220 me = ME_INT_BND;
00221 } else if (m == f_max) {
00222 fst()->max(m-1); holes += 1;
00223 } else {
00224
00225 RangeList* f = new (home) RangeList(f_min,m-1);
00226 f->prevnext(NULL,fst());
00227 fst()->min(m+1); fst()->prev(NULL,f);
00228 fst(f); holes += 1;
00229 }
00230 } else if (m > lst()->prev(NULL)->max()) {
00231 int l_min = lst()->min();
00232 if (m < l_min)
00233 return ME_INT_NONE;
00234 int l_max = dom.max();
00235 if ((m == l_min) && (m == l_max)) {
00236 RangeList* l_prev = lst()->prev(NULL);
00237 dom.max(l_prev->max());
00238 if (l_prev == fst()) {
00239
00240 l_prev->dispose(home,lst());
00241 fst(NULL); holes = 0;
00242 me = assigned() ? ME_INT_VAL : ME_INT_BND;
00243 } else {
00244 l_prev->next(lst(),NULL);
00245 lst()->dispose(home); lst(l_prev);
00246 holes -= l_max - dom.max() - 1;
00247 me = ME_INT_BND;
00248 }
00249 } else if (m == l_max) {
00250 dom.max(m-1); lst()->max(m-1);
00251 me = ME_INT_BND;
00252 } else if (m == l_min) {
00253 lst()->min(m+1); holes += 1;
00254 } else {
00255 RangeList* l = new (home) RangeList(m+1,l_max);
00256 l->prevnext(lst(),NULL);
00257 lst()->max(m-1); lst()->next(NULL,l);
00258 lst(l); holes += 1;
00259 }
00260 } else {
00261 RangeList* p;
00262 RangeList* c;
00263 RangeList* n;
00264 if (closer_min(m)) {
00265 assert(m > fst()->max());
00266 p = NULL;
00267 c = fst();
00268 do {
00269 n=c->next(p); p=c; c=n;
00270 } while (m > c->max());
00271 if (m < c->min())
00272 return ME_INT_NONE;
00273 n=c->next(p);
00274 } else {
00275 assert(m < lst()->min());
00276 n = NULL;
00277 c = lst();
00278 do {
00279 p=c->prev(n); n=c; c=p;
00280 } while (m < c->min());
00281 if (m > c->max())
00282 return ME_INT_NONE;
00283 p=c->prev(n);
00284 }
00285 assert((fst() != c) && (lst() != c));
00286 assert((m >= c->min()) && (m <= c->max()));
00287 holes += 1;
00288 int c_min = c->min();
00289 int c_max = c->max();
00290 if ((c_min == m) && (c_max == m)) {
00291 c->dispose(home);
00292 p->next(c,n); n->prev(c,p);
00293 } else if (c_min == m) {
00294 c->min(m+1);
00295 } else {
00296 c->max(m-1);
00297 if (c_max != m) {
00298 RangeList* l = new (home) RangeList(m+1,c_max);
00299 l->prevnext(c,n);
00300 c->next(n,l);
00301 n->prev(c,l);
00302 }
00303 }
00304 }
00305 IntDelta d(m,m);
00306 return notify(home,me,&d);
00307 }
00308
00309
00310
00311
00312
00313
00314
00315
00316 forceinline
00317 IntVarImp::IntVarImp(Space* home, bool share, IntVarImp& x)
00318 : IntVarImpBase(home,share,x), dom(x.dom.min(),x.dom.max()) {
00319 holes = x.holes;
00320 if (holes) {
00321 int m = 1;
00322
00323 {
00324 RangeList* s_p = x.fst();
00325 RangeList* s_c = s_p->next(NULL);
00326 do {
00327 m++;
00328 RangeList* s_n = s_c->next(s_p); s_p=s_c; s_c=s_n;
00329 } while (s_c != NULL);
00330 }
00331 RangeList* d_c =
00332 static_cast<RangeList*>(home->alloc(m*sizeof(RangeList)));
00333 fst(d_c); lst(d_c+m-1);
00334 d_c->min(x.fst()->min());
00335 d_c->max(x.fst()->max());
00336 d_c->prevnext(NULL,NULL);
00337 RangeList* s_p = x.fst();
00338 RangeList* s_c = s_p->next(NULL);
00339 do {
00340 RangeList* d_n = d_c + 1;
00341 d_c->next(NULL,d_n);
00342 d_n->prevnext(d_c,NULL);
00343 d_n->min(s_c->min()); d_n->max(s_c->max());
00344 d_c = d_n;
00345 RangeList* s_n=s_c->next(s_p); s_p=s_c; s_c=s_n;
00346 } while (s_c != NULL);
00347 d_c->next(NULL,NULL);
00348 } else {
00349 fst(NULL);
00350 }
00351 }
00352
00353 IntVarImp*
00354 IntVarImp::perform_copy(Space* home, bool share) {
00355 return new (home) IntVarImp(home,share,*this);
00356 }
00357
00358 Reflection::Arg*
00359 IntVarImp::spec(const Space*, Reflection::VarMap& m) const {
00360 int varIndex = m.index(this);
00361 if (varIndex != -1)
00362 return Reflection::Arg::newVar(varIndex);
00363
00364 int count = 0;
00365 const RangeList* p=NULL;
00366 const RangeList* c=ranges_fwd();
00367 while (c != NULL) {
00368 const RangeList* n = c->next(p); p=c; c=n;
00369 count++;
00370 }
00371 Reflection::IntArrayArg* args = Reflection::Arg::newIntArray(count*2);
00372
00373 Reflection::VarSpec* spec = new Reflection::VarSpec(vti, args,
00374 assigned());
00375
00376 count = 0;
00377 p=NULL;
00378 c=ranges_fwd();
00379 while (c != NULL) {
00380 (*args)[count++] = c->min();
00381 (*args)[count++] = c->max();
00382 const RangeList* n = c->next(p); p=c; c=n;
00383 }
00384
00385 return Reflection::Arg::newVar(m.put(this, spec));
00386 }
00387
00388 VarImpBase*
00389 IntVarImp::create(Space* home, Reflection::VarSpec& spec) {
00390 Reflection::IntArrayArgRanges ai(spec.dom()->toIntArray());
00391 return new (home) IntVarImp(home, IntSet(ai));
00392 }
00393
00394 void
00395 IntVarImp::constrain(Space* home, VarImpBase* v,
00396 Reflection::VarSpec& spec) {
00397 Reflection::IntArrayArgRanges ai(spec.dom()->toIntArray());
00398 GECODE_ME_FAIL(home,
00399 static_cast<Int::IntVarImp*>(v)->inter_r(home, ai, false));
00400 }
00401
00402 namespace {
00403 Reflection::VarImpRegistrar<IntVarImp> registerIntVarImp;
00404 }
00405
00406 }}
00407
00408