lds.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
00041 #include "gecode/search.hh"
00042
00043 namespace Gecode { namespace Search {
00044
00045
00046
00047
00048
00049
00050
00051 forceinline
00052 ProbeEngine::ProbeNode
00053 ::ProbeNode(Space* s, const BranchingDesc* d, unsigned int a)
00054 : _space(s), _desc(d), _alt(a) {}
00055
00056 forceinline Space*
00057 ProbeEngine::ProbeNode::space(void) const {
00058 return _space;
00059 }
00060
00061 forceinline const BranchingDesc*
00062 ProbeEngine::ProbeNode::desc(void) const {
00063 return _desc;
00064 }
00065
00066 forceinline unsigned int
00067 ProbeEngine::ProbeNode::alt(void) const {
00068 return _alt;
00069 }
00070
00071 forceinline void
00072 ProbeEngine::ProbeNode::next(void) {
00073 _alt--;
00074 }
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084 forceinline
00085 ProbeEngine::ProbeEngine(Stop* st, size_t sz)
00086 : EngineCtrl(st,sz) {}
00087
00088 forceinline void
00089 ProbeEngine::init(Space* s, unsigned int d0) {
00090 cur = s;
00091 d = d0;
00092 exhausted = true;
00093 }
00094
00095 forceinline void
00096 ProbeEngine::reset(Space* s, unsigned int d0) {
00097 delete cur;
00098 assert(ds.empty());
00099 cur = s;
00100 d = d0;
00101 exhausted = true;
00102 EngineCtrl::reset(s);
00103 }
00104
00105 forceinline size_t
00106 ProbeEngine::stacksize(void) const {
00107 return ds.size();
00108 }
00109
00110 forceinline bool
00111 ProbeEngine::done(void) const {
00112 return exhausted;
00113 }
00114
00115 forceinline
00116 ProbeEngine::~ProbeEngine(void) {
00117 delete cur;
00118 while (!ds.empty())
00119 delete ds.pop().space();
00120 }
00121
00122 forceinline Space*
00123 ProbeEngine::explore(void) {
00124 start();
00125 while (true) {
00126 if (cur == NULL) {
00127 backtrack:
00128 if (ds.empty())
00129 return NULL;
00130 if (stop(stacksize()))
00131 return NULL;
00132 unsigned int a = ds.top().alt();
00133 const BranchingDesc* desc = ds.top().desc();
00134 if (a == 0) {
00135 cur = ds.pop().space();
00136 EngineCtrl::pop(cur,desc);
00137 cur->commit(desc,0);
00138 delete desc;
00139 } else {
00140 ds.top().next();
00141 cur = ds.top().space()->clone();
00142 clone++;
00143 cur->commit(desc,a);
00144 }
00145 EngineCtrl::current(cur);
00146 d++;
00147 }
00148 check_discrepancy:
00149 if (d == 0) {
00150 Space* s = cur;
00151 while (s->status(propagate) == SS_BRANCH) {
00152 const BranchingDesc* desc = s->description();
00153 if (desc->alternatives() > 1)
00154 exhausted = false;
00155 s->commit(desc,0);
00156 delete desc;
00157 }
00158 cur = NULL;
00159 EngineCtrl::current(NULL);
00160 if (s->failed()) {
00161 delete s;
00162 goto backtrack;
00163 }
00164 return s;
00165 }
00166 switch (cur->status(propagate)) {
00167 case SS_FAILED:
00168 fail++;
00169 case SS_SOLVED:
00170 delete cur;
00171 cur = NULL;
00172 EngineCtrl::current(NULL);
00173 goto backtrack;
00174 case SS_BRANCH:
00175 {
00176 const BranchingDesc* desc = cur->description();
00177 unsigned int alt = desc->alternatives();
00178 if (alt > 1) {
00179 if (d < alt-1)
00180 exhausted = false;
00181 unsigned int d_a = (d >= alt-1) ? alt-1 : d;
00182 Space* cc = cur->clone();
00183 EngineCtrl::push(cc,desc);
00184 ProbeNode sn(cc,desc,d_a-1);
00185 clone++;
00186 ds.push(sn);
00187 cur->commit(desc,d_a);
00188 d -= d_a;
00189 } else {
00190 cur->commit(desc,0);
00191 delete desc;
00192 }
00193 commit++;
00194 goto check_discrepancy;
00195 }
00196 default: GECODE_NEVER;
00197 }
00198 }
00199 }
00200
00201
00202
00203
00204
00205
00206
00207 LDS::LDS(Space* s, unsigned int d, Stop* st, size_t sz)
00208 : root(NULL), d_cur(0), d_max(d), e(st,sz) {
00209 if (s->status(e.propagate) == SS_FAILED) {
00210 e.init(NULL,0);
00211 e.fail += 1;
00212 e.current(s);
00213 } else {
00214 e.clone++;;
00215 Space* c = s->clone();
00216 if (d_max > 0) {
00217 root = c->clone();
00218 e.clone++;
00219 }
00220 e.init(c,0);
00221 e.current(s);
00222 e.current(NULL);
00223 e.current(c);
00224 }
00225 }
00226
00227 LDS::~LDS(void) {
00228 delete root;
00229 }
00230
00231 Space*
00232 LDS::next(void) {
00233 while (true) {
00234 Space* s = e.explore();
00235 if (s != NULL)
00236 return s;
00237 if (((s == NULL) && e.stopped()) || (++d_cur > d_max) || e.done())
00238 break;
00239 if (d_cur == d_max) {
00240 if (root != NULL)
00241 e.reset(root,d_cur);
00242 root = NULL;
00243 } else if (root != NULL) {
00244 e.clone++;
00245 e.reset(root->clone(),d_cur);
00246 }
00247 }
00248 return NULL;
00249 }
00250
00251 bool
00252 LDS::stopped(void) const {
00253 return e.stopped();
00254 }
00255
00256 Statistics
00257 LDS::statistics(void) const {
00258 Statistics s = e;
00259 s.memory += e.stacksize();
00260 return e;
00261 }
00262
00263 }}
00264
00265