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 namespace Gecode { namespace Search {
00023
00024
00025
00026
00027
00028
00029 forceinline
00030 ReCoNode::ReCoNode(Space* s, Space* c)
00031 : _space(c), _alt(0), _desc(s->description()) {}
00032
00033 forceinline Space*
00034 ReCoNode::space(void) const {
00035 return _space;
00036 }
00037 forceinline void
00038 ReCoNode::space(Space* s) {
00039 _space = s;
00040 }
00041
00042 forceinline unsigned int
00043 ReCoNode::alt(void) const {
00044 return _alt;
00045 }
00046 forceinline bool
00047 ReCoNode::rightmost(void) const {
00048 return _alt+1 == _desc->alternatives();
00049 }
00050 forceinline void
00051 ReCoNode::next(void) {
00052 _alt++;
00053 }
00054
00055 forceinline const BranchingDesc*
00056 ReCoNode::desc(void) const {
00057 return _desc;
00058 }
00059
00060 forceinline void
00061 ReCoNode::dispose(void) {
00062 delete _space;
00063 delete _desc;
00064 }
00065
00066
00067
00068
00069
00070
00071
00072
00073 forceinline
00074 ReCoStack::ReCoStack(unsigned int a_d0) : a_d(a_d0) {}
00075
00076 forceinline const BranchingDesc*
00077 ReCoStack::push(Space* s, Space* c) {
00078 ReCoNode sn(s,c);
00079 ds.push(sn);
00080 return sn.desc();
00081 }
00082
00083 forceinline bool
00084 ReCoStack::next(EngineCtrl& stat) {
00085
00086 while (!ds.empty())
00087 if (ds.top().rightmost()) {
00088 stat.pop(ds.top().space(),ds.top().desc());
00089 ds.pop().dispose();
00090 } else {
00091 ds.top().next();
00092 return true;
00093 }
00094 return false;
00095 }
00096
00097 forceinline void
00098 ReCoStack::commit(Space* s, int i) const {
00099 const ReCoNode& n = ds[i];
00100 s->commit(n.desc(),n.alt());
00101 }
00102
00103 forceinline int
00104 ReCoStack::lc(Space*& s) const {
00105 int l = ds.entries()-1;
00106 while (ds[l].space() == NULL)
00107 l--;
00108 s = ds[l].space();
00109 return l;
00110 }
00111
00112 forceinline int
00113 ReCoStack::entries(void) const {
00114 return ds.entries();
00115 }
00116
00117 forceinline size_t
00118 ReCoStack::stacksize(void) const {
00119 return ds.size();
00120 }
00121
00122 forceinline void
00123 ReCoStack::unwind(int l) {
00124 assert((ds[l].space() == NULL) || ds[l].space()->failed());
00125 int n = ds.entries();
00126 for (int i=l; i<n; i++)
00127 ds.pop().dispose();
00128 assert(ds.entries() == l);
00129 }
00130
00131 inline void
00132 ReCoStack::reset(void) {
00133 while (!ds.empty())
00134 ds.pop().dispose();
00135 }
00136
00137 template <bool constrained>
00138 forceinline Space*
00139 ReCoStack::recompute(unsigned int& d, EngineCtrl& stat) {
00140 assert(!ds.empty());
00141
00142
00143
00144
00145 if ((ds.top().space() != NULL) && ds.top().rightmost()) {
00146 Space* s = ds.top().space();
00147 s->commit(ds.top().desc(),ds.top().alt());
00148 ds.top().space(NULL);
00149 stat.lao(s);
00150 d = 0;
00151 stat.commit++;
00152 return s;
00153 }
00154
00155 Space* s;
00156 int l = lc(s);
00157 int n = ds.entries();
00158 d = n - l;
00159
00160 if (constrained) {
00161
00162
00163 if (s->status(stat.propagate) == SS_FAILED) {
00164
00165 stat.fail++;
00166 unwind(l);
00167 return NULL;
00168 }
00169
00170
00171
00172 Space* c = s->clone(true,stat.propagate);
00173 ds[l].space(c);
00174 stat.constrained(s,c);
00175 } else {
00176 s = s->clone(true,stat.propagate);
00177 }
00178 stat.clone++;
00179
00180 if (d < a_d) {
00181
00182 for (int i=l; i<n; i++)
00183 commit(s,i);
00184 } else {
00185 int m = l + (d >> 1);
00186 int i = l;
00187
00188 for (; i<m; i++ )
00189 commit(s,i);
00190
00191 for (; (i<n) && ds[i].rightmost(); i++)
00192 commit(s,i);
00193
00194 if (i<n-1) {
00195
00196 if (constrained && s->status(stat.propagate) == SS_FAILED) {
00197
00198 delete s;
00199 stat.commit += (i-l);
00200 stat.fail++;
00201 unwind(i);
00202 return NULL;
00203 }
00204 stat.clone++;
00205 ds[i].space(s->clone(true,stat.propagate));
00206 stat.adapt(ds[i].space());
00207 d = n-i;
00208 }
00209
00210 for (; i<n; i++)
00211 commit(s,i);
00212 }
00213 stat.commit += d;
00214 return s;
00215 }
00216
00217 }}
00218
00219