reco-stack.icc
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 namespace Gecode { namespace Search {
00039
00040
00041
00042
00043
00044
00045 forceinline
00046 ReCoNode::ReCoNode(Space* s, Space* c)
00047 : _space(c), _alt(0), _desc(s->description()) {}
00048
00049 forceinline Space*
00050 ReCoNode::space(void) const {
00051 return _space;
00052 }
00053 forceinline void
00054 ReCoNode::space(Space* s) {
00055 _space = s;
00056 }
00057
00058 forceinline unsigned int
00059 ReCoNode::alt(void) const {
00060 return _alt;
00061 }
00062 forceinline bool
00063 ReCoNode::rightmost(void) const {
00064 return _alt+1 == _desc->alternatives();
00065 }
00066 forceinline void
00067 ReCoNode::next(void) {
00068 _alt++;
00069 }
00070
00071 forceinline const BranchingDesc*
00072 ReCoNode::desc(void) const {
00073 return _desc;
00074 }
00075
00076 forceinline void
00077 ReCoNode::dispose(void) {
00078 delete _space;
00079 delete _desc;
00080 }
00081
00082
00083
00084
00085
00086
00087
00088
00089 forceinline
00090 ReCoStack::ReCoStack(unsigned int a_d0) : a_d(a_d0) {}
00091
00092 forceinline const BranchingDesc*
00093 ReCoStack::push(Space* s, Space* c) {
00094 ReCoNode sn(s,c);
00095 ds.push(sn);
00096 return sn.desc();
00097 }
00098
00099 template <class DescType>
00100 forceinline const BranchingDesc*
00101 ReCoStack::nextDesc(EngineCtrl& stat, int& alt, int& closedDescs) {
00102 closedDescs = 0;
00103 while (!ds.empty())
00104 if (ds.top().rightmost()) {
00105 stat.pop(ds.top().space(),ds.top().desc());
00106 if (dynamic_cast<const DescType*>(ds.top().desc()))
00107 closedDescs++;
00108 ds.pop().dispose();
00109 } else {
00110 ds.top().next();
00111 alt = ds.top().alt();
00112 return ds.top().desc();
00113 }
00114 return NULL;
00115 }
00116
00117 template <class DescType, bool inclusive>
00118 forceinline void
00119 ReCoStack::closeBranch(EngineCtrl& stat) {
00120 while (!ds.empty()) {
00121 if (dynamic_cast<const DescType*>(ds.top().desc())) {
00122 if (inclusive && !ds.empty()) {
00123 stat.pop(ds.top().space(),ds.top().desc());
00124 ds.pop().dispose();
00125 }
00126 break;
00127 }
00128 stat.pop(ds.top().space(),ds.top().desc());
00129 ds.pop().dispose();
00130 }
00131 }
00132
00133 forceinline bool
00134 ReCoStack::next(EngineCtrl& stat) {
00135
00136 while (!ds.empty())
00137 if (ds.top().rightmost()) {
00138 stat.pop(ds.top().space(),ds.top().desc());
00139 ds.pop().dispose();
00140 } else {
00141 ds.top().next();
00142 return true;
00143 }
00144 return false;
00145 }
00146
00147 forceinline void
00148 ReCoStack::commit(Space* s, int i) const {
00149 const ReCoNode& n = ds[i];
00150 s->commit(n.desc(),n.alt());
00151 }
00152
00153 forceinline int
00154 ReCoStack::lc(Space*& s) const {
00155 int l = ds.entries()-1;
00156 while (ds[l].space() == NULL)
00157 l--;
00158 s = ds[l].space();
00159 return l;
00160 }
00161
00162 forceinline int
00163 ReCoStack::entries(void) const {
00164 return ds.entries();
00165 }
00166
00167 forceinline size_t
00168 ReCoStack::stacksize(void) const {
00169 return ds.size();
00170 }
00171
00172 forceinline void
00173 ReCoStack::unwind(int l) {
00174 assert((ds[l].space() == NULL) || ds[l].space()->failed());
00175 int n = ds.entries();
00176 for (int i=l; i<n; i++)
00177 ds.pop().dispose();
00178 assert(ds.entries() == l);
00179 }
00180
00181 inline void
00182 ReCoStack::reset(void) {
00183 while (!ds.empty())
00184 ds.pop().dispose();
00185 }
00186
00187 template <bool constrained>
00188 forceinline Space*
00189 ReCoStack::recompute(unsigned int& d, EngineCtrl& stat) {
00190 assert(!ds.empty());
00191
00192
00193
00194
00195 if ((ds.top().space() != NULL) && ds.top().rightmost()) {
00196 Space* s = ds.top().space();
00197 s->commit(ds.top().desc(),ds.top().alt());
00198 ds.top().space(NULL);
00199 stat.lao(s);
00200 d = 0;
00201 stat.commit++;
00202 return s;
00203 }
00204
00205 Space* s;
00206 int l = lc(s);
00207 int n = ds.entries();
00208 d = static_cast<unsigned int>(n - l);
00209
00210 if (constrained) {
00211
00212
00213 if (s->status(stat.propagate) == SS_FAILED) {
00214
00215 stat.fail++;
00216 unwind(l);
00217 return NULL;
00218 }
00219
00220
00221
00222 Space* c = s->clone();
00223 ds[l].space(c);
00224 stat.constrained(s,c);
00225 } else {
00226 s = s->clone();
00227 }
00228 stat.clone++;
00229
00230 if (d < a_d) {
00231
00232 for (int i=l; i<n; i++)
00233 commit(s,i);
00234 } else {
00235 int m = l + static_cast<int>(d >> 1);
00236 int i = l;
00237
00238 for (; i<m; i++ )
00239 commit(s,i);
00240
00241 for (; (i<n) && ds[i].rightmost(); i++)
00242 commit(s,i);
00243
00244 if (i<n-1) {
00245
00246 SpaceStatus ss = s->status(stat.propagate);
00247
00248
00249
00250
00251
00252
00253
00254 if (ss == SS_FAILED) {
00255
00256 delete s;
00257 stat.commit += (i-l);
00258 stat.fail++;
00259 unwind(i);
00260 return NULL;
00261 }
00262 stat.clone++;
00263 ds[i].space(s->clone());
00264 stat.adapt(ds[i].space());
00265 d = static_cast<unsigned int>(n-i);
00266 }
00267
00268 for (; i<n; i++)
00269 commit(s,i);
00270 }
00271 stat.commit += d;
00272 return s;
00273 }
00274
00275 }}
00276
00277