path.hh
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 #ifndef __GECODE_SEARCH_SEQUENTIAL_PATH_HH__
00039 #define __GECODE_SEARCH_SEQUENTIAL_PATH_HH__
00040
00041 #include <gecode/search.hh>
00042
00043 namespace Gecode { namespace Search { namespace Sequential {
00044
00058 class Path {
00059 public:
00061 class Node {
00062 protected:
00064 Space* _space;
00066 unsigned int _alt;
00068 const BranchingDesc* _desc;
00069 public:
00071 Node(void);
00073 Node(Space* s, Space* c);
00074
00076 Space* space(void) const;
00078 void space(Space* s);
00079
00081 const BranchingDesc* desc(void) const;
00082
00084 unsigned int alt(void) const;
00086 bool rightmost(void) const;
00088 void next(void);
00089
00091 void dispose(void);
00092 };
00094 Support::DynamicStack<Node,Heap> ds;
00095 public:
00097 Path(void);
00099 const BranchingDesc* push(Worker& stat, Space* s, Space* c);
00101 bool next(Worker& s);
00103 int lc(void) const;
00105 void unwind(int l);
00107 void commit(Space* s, int i) const;
00109 Space* recompute(unsigned int& d, unsigned int a_d, Worker& s);
00111 Space* recompute(unsigned int& d, unsigned int a_d, Worker& s,
00112 const Space* best, int& mark);
00114 int entries(void) const;
00116 size_t size(void) const;
00118 void reset(void);
00119 };
00120
00121
00122
00123
00124
00125
00126 forceinline
00127 Path::Node::Node(void) {}
00128
00129 forceinline
00130 Path::Node::Node(Space* s, Space* c)
00131 : _space(c), _alt(0), _desc(s->description()) {}
00132
00133 forceinline Space*
00134 Path::Node::space(void) const {
00135 return _space;
00136 }
00137 forceinline void
00138 Path::Node::space(Space* s) {
00139 _space = s;
00140 }
00141
00142 forceinline unsigned int
00143 Path::Node::alt(void) const {
00144 return _alt;
00145 }
00146 forceinline bool
00147 Path::Node::rightmost(void) const {
00148 return _alt+1 == _desc->alternatives();
00149 }
00150 forceinline void
00151 Path::Node::next(void) {
00152 _alt++;
00153 }
00154
00155 forceinline const BranchingDesc*
00156 Path::Node::desc(void) const {
00157 return _desc;
00158 }
00159
00160 forceinline void
00161 Path::Node::dispose(void) {
00162 delete _space;
00163 delete _desc;
00164 }
00165
00166
00167
00168
00169
00170
00171
00172
00173 forceinline
00174 Path::Path(void) : ds(heap) {}
00175
00176 forceinline const BranchingDesc*
00177 Path::push(Worker& stat, Space* s, Space* c) {
00178 Node sn(s,c);
00179 ds.push(sn);
00180 stat.stack_depth(static_cast<unsigned long int>(ds.entries()));
00181 return sn.desc();
00182 }
00183
00184 forceinline bool
00185 Path::next(Worker& stat) {
00186
00187 while (!ds.empty())
00188 if (ds.top().rightmost()) {
00189 stat.pop(ds.top().space(),ds.top().desc());
00190 ds.pop().dispose();
00191 } else {
00192 ds.top().next();
00193 return true;
00194 }
00195 return false;
00196 }
00197
00198 forceinline void
00199 Path::commit(Space* s, int i) const {
00200 const Node& n = ds[i];
00201 s->commit(*n.desc(),n.alt());
00202 }
00203
00204 forceinline int
00205 Path::lc(void) const {
00206 int l = ds.entries()-1;
00207 while (ds[l].space() == NULL)
00208 l--;
00209 return l;
00210 }
00211
00212 forceinline int
00213 Path::entries(void) const {
00214 return ds.entries();
00215 }
00216
00217 forceinline size_t
00218 Path::size(void) const {
00219 return ds.size();
00220 }
00221
00222 forceinline void
00223 Path::unwind(int l) {
00224 assert((ds[l].space() == NULL) || ds[l].space()->failed());
00225 int n = ds.entries();
00226 for (int i=l; i<n; i++)
00227 ds.pop().dispose();
00228 assert(ds.entries() == l);
00229 }
00230
00231 inline void
00232 Path::reset(void) {
00233 while (!ds.empty())
00234 ds.pop().dispose();
00235 }
00236
00237 forceinline Space*
00238 Path::recompute(unsigned int& d, unsigned int a_d, Worker& stat) {
00239 assert(!ds.empty());
00240
00241
00242
00243
00244 if ((ds.top().space() != NULL) && ds.top().rightmost()) {
00245 Space* s = ds.top().space();
00246 s->commit(*ds.top().desc(),ds.top().alt());
00247 assert(ds.entries()-1 == lc());
00248 ds.top().space(NULL);
00249 stat.lao(s);
00250 d = 0;
00251 return s;
00252 }
00253
00254 int l = lc();
00255 int n = ds.entries();
00256
00257 d = static_cast<unsigned int>(n - l);
00258
00259 Space* s = ds[l].space()->clone();
00260
00261 if (d < a_d) {
00262
00263 for (int i=l; i<n; i++)
00264 commit(s,i);
00265 } else {
00266 int m = l + static_cast<int>(d >> 1);
00267 int i = l;
00268
00269 for (; i<m; i++ )
00270 commit(s,i);
00271
00272 for (; (i<n) && ds[i].rightmost(); i++)
00273 commit(s,i);
00274
00275 if (i<n-1) {
00276
00277 SpaceStatus ss = s->status(stat);
00278
00279
00280
00281
00282 if (ss == SS_FAILED) {
00283
00284 delete s;
00285 stat.fail++;
00286 unwind(i);
00287 return NULL;
00288 }
00289 ds[i].space(s->clone());
00290 stat.adapt(ds[i].space());
00291 d = static_cast<unsigned int>(n-i);
00292 }
00293
00294 for (; i<n; i++)
00295 commit(s,i);
00296 }
00297 return s;
00298 }
00299
00300 forceinline Space*
00301 Path::recompute(unsigned int& d, unsigned int a_d, Worker& stat,
00302 const Space* best, int& mark) {
00303 assert(!ds.empty());
00304
00305
00306
00307
00308 if ((ds.top().space() != NULL) && ds.top().rightmost()) {
00309 Space* s = ds.top().space();
00310 s->commit(*ds.top().desc(),ds.top().alt());
00311 assert(ds.entries()-1 == lc());
00312 if (mark > ds.entries()-1) {
00313 mark = ds.entries()-1;
00314 s->constrain(*best);
00315 }
00316 ds.top().space(NULL);
00317 stat.lao(s);
00318 d = 0;
00319 return s;
00320 }
00321
00322 int l = lc();
00323 int n = ds.entries();
00324
00325 d = static_cast<unsigned int>(n - l);
00326
00327 Space* s = ds[l].space();
00328
00329 if (l < mark) {
00330 mark = l;
00331 s->constrain(*best);
00332
00333
00334 if (s->status(stat) == SS_FAILED) {
00335
00336 stat.fail++;
00337 unwind(l);
00338 return NULL;
00339 }
00340
00341
00342
00343 Space* c = s->clone();
00344 ds[l].space(c);
00345 stat.constrained(s,c);
00346 } else {
00347 s = s->clone();
00348 }
00349
00350 if (d < a_d) {
00351
00352 for (int i=l; i<n; i++)
00353 commit(s,i);
00354 } else {
00355 int m = l + static_cast<int>(d >> 1);
00356 int i = l;
00357
00358 for (; i<m; i++ )
00359 commit(s,i);
00360
00361 for (; (i<n) && ds[i].rightmost(); i++)
00362 commit(s,i);
00363
00364 if (i<n-1) {
00365
00366 SpaceStatus ss = s->status(stat);
00367
00368
00369
00370
00371
00372
00373
00374 if (ss == SS_FAILED) {
00375
00376 delete s;
00377 stat.fail++;
00378 unwind(i);
00379 return NULL;
00380 }
00381 ds[i].space(s->clone());
00382 stat.adapt(ds[i].space());
00383 d = static_cast<unsigned int>(n-i);
00384 }
00385
00386 for (; i<n; i++)
00387 commit(s,i);
00388 }
00389 return s;
00390 }
00391
00392 }}}
00393
00394 #endif
00395
00396