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/gist/spacenode.hh>
00039 #include <gecode/gist/visualnode.hh>
00040 #include <gecode/search.hh>
00041 #include <stack>
00042
00043 namespace Gecode { namespace Gist {
00044
00045
00046 enum BranchKind {
00047 BK_NORMAL, BK_SPECIAL_IN, BK_SPECIAL_OUT, BK_STEP
00048 };
00049
00051 class Branch {
00052 public:
00054 int alternative;
00056 SpaceNode* ownBest;
00057 const BranchKind branchKind;
00058 union {
00060 const SpecialDesc* special;
00062 const BranchingDesc* branch;
00064 const StepDesc* step;
00065 } desc;
00066
00068 Branch(int a, const BranchingDesc* d, SpaceNode* best = NULL, BranchKind bk = BK_NORMAL)
00069 : alternative(a), ownBest(best), branchKind(bk) {
00070 desc.branch = d;
00071 }
00072 Branch(int a, const SpecialDesc* d, BranchKind bk, SpaceNode* best = NULL)
00073 : alternative(a), ownBest(best), branchKind(bk) {
00074 desc.special = d;
00075 }
00076 Branch(int a, const StepDesc* d, BranchKind bk, SpaceNode* best = NULL)
00077 : alternative(a), ownBest(best), branchKind(bk) {
00078 desc.step = d;
00079 }
00080 };
00081
00082 StepDesc::StepDesc(int steps) : noOfSteps(steps), debug(false) { }
00083
00084 void
00085 StepDesc::toggleDebug(void) {
00086 debug = !debug;
00087 }
00088
00089 SpecialDesc::SpecialDesc(std::string varName, int rel0, int v0)
00090 : vn(varName), v(v0), rel(rel0) { }
00091
00092 BestNode::BestNode(SpaceNode* s0) : s(s0) {}
00093
00094 int
00095 SpaceNode::recompute(BestNode* curBest, int c_d, int a_d) {
00096 int rdist = 0;
00097
00098 if (workingSpace == NULL) {
00099 SpaceNode* curNode = this;
00100 SpaceNode* lastFixpoint = NULL;
00101
00102 if(curNode->getStatus() != SPECIAL && curNode->getStatus() != STEP) {
00103 lastFixpoint = curNode;
00104 }
00105
00106 std::stack<Branch> stck;
00107 bool specialNodeOnPath = false;
00108
00109 while (curNode->copy == NULL) {
00110 SpaceNode* parent = curNode->getParent();
00111 int alternative = curNode->getAlternative();
00112
00113 if(curNode->getStatus() == STEP) {
00114 Branch b(alternative, curNode->desc.step, BK_STEP);
00115 stck.push(b);
00116 if(lastFixpoint == NULL && parent->getStatus() == BRANCH) {
00117 lastFixpoint = parent;
00118 }
00119 } else if(curNode->getStatus() == SPECIAL) {
00120 Branch b(alternative, curNode->desc.special, BK_SPECIAL_IN);
00121 stck.push(b);
00122 if(lastFixpoint == NULL && parent->getStatus() == BRANCH) {
00123 lastFixpoint = parent;
00124 }
00125 specialNodeOnPath = true;
00126
00127 } else if(parent->getStatus() == SPECIAL || parent->getStatus() == STEP) {
00128 Branch b(alternative, curNode->desc.special, BK_SPECIAL_OUT);
00129 stck.push(b);
00130 } else {
00131 Branch b(alternative, parent->desc.branch,
00132 curBest == NULL ? NULL : curNode->ownBest);
00133 stck.push(b);
00134 }
00135
00136 curNode = parent;
00137 rdist++;
00138 }
00139 Space* curSpace = curNode->copy->clone();
00140
00141 SpaceNode* lastBest = NULL;
00142 SpaceNode* middleNode = curNode;
00143 int curDist = 0;
00144
00145 while (!stck.empty()) {
00146 if (a_d >= 0 &&
00147 curDist > a_d &&
00148 middleNode->getStatus() != SPECIAL &&
00149 middleNode->getStatus() != STEP &&
00150 curDist == rdist / 2) {
00151 if (curSpace->status() == SS_FAILED) {
00152 workingSpace = curSpace;
00153 return rdist;
00154 } else {
00155 middleNode->copy = curSpace->clone();
00156 }
00157 }
00158 Branch b = stck.top(); stck.pop();
00159
00160 if(middleNode == lastFixpoint) {
00161 curSpace->status();
00162 }
00163
00164 switch (b.branchKind) {
00165 case BK_NORMAL:
00166 {
00167 curSpace->commit(*b.desc.branch, b.alternative);
00168 }
00169 break;
00170 case BK_STEP:
00171 {
00172 }
00173 break;
00174 case BK_SPECIAL_IN:
00175 {
00176 }
00177 break;
00178 case BK_SPECIAL_OUT:
00179
00180 break;
00181 }
00182
00183 if (b.ownBest != NULL && b.ownBest != lastBest) {
00184 b.ownBest->acquireSpace(curBest, c_d, a_d);
00185 if (b.ownBest->workingSpace->status() != SS_SOLVED) {
00186
00187
00188 Space* dfsSpace = Gecode::dfs(b.ownBest->workingSpace);
00189 delete b.ownBest->workingSpace;
00190 b.ownBest->workingSpace = dfsSpace;
00191 }
00192 curSpace->constrain(*b.ownBest->workingSpace);
00193 lastBest = b.ownBest;
00194 }
00195 curDist++;
00196 middleNode = middleNode->getChild(b.alternative);
00197 }
00198 workingSpace = curSpace;
00199
00200 }
00201 return rdist;
00202 }
00203
00204 void
00205 SpaceNode::acquireSpace(BestNode* curBest, int c_d, int a_d) {
00206 SpaceNode* p = getParent();
00207
00208 if (getStatus() == UNDETERMINED && curBest != NULL && ownBest == NULL &&
00209 p != NULL && curBest->s != p->ownBest) {
00210 ownBest = curBest->s;
00211 }
00212
00213 if (getStatus() != SPECIAL && getStatus() != STEP) {
00214 if (workingSpace == NULL && p != NULL && p->workingSpace != NULL) {
00215
00216 workingSpace = p->workingSpace;
00217 p->workingSpace = NULL;
00218 if (p->desc.branch != NULL)
00219 workingSpace->commit(*p->desc.branch, getAlternative());
00220
00221 if (ownBest != NULL) {
00222 ownBest->acquireSpace(curBest, c_d, a_d);
00223 if (ownBest->workingSpace->status() != SS_SOLVED) {
00224
00225
00226 Space* dfsSpace = Gecode::dfs(ownBest->workingSpace);
00227 delete ownBest->workingSpace;
00228 ownBest->workingSpace = dfsSpace;
00229 }
00230 workingSpace->constrain(*ownBest->workingSpace);
00231 }
00232 }
00233 }
00234
00235 if (workingSpace == NULL) {
00236 if (recompute(curBest, c_d, a_d) > c_d && c_d >= 0 &&
00237 getStatus() != SPECIAL && getStatus() != STEP &&
00238 workingSpace->status() == SS_BRANCH) {
00239 copy = workingSpace->clone();
00240 }
00241 }
00242
00243 if (getStatus() != SPECIAL && getStatus() != STEP) {
00244
00245 workingSpace->status();
00246 if (copy == NULL && p != NULL && isOpen() &&
00247 p->copy != NULL && p->getNoOfOpenChildren() == 1 &&
00248 p->getParent() != NULL) {
00249
00250 copy = p->copy;
00251 p->copy = NULL;
00252
00253 if(p->desc.branch != NULL)
00254 copy->commit(*p->desc.branch, getAlternative());
00255
00256 if (ownBest != NULL) {
00257 ownBest->acquireSpace(curBest, c_d, a_d);
00258 if (ownBest->workingSpace->status() != SS_SOLVED) {
00259
00260
00261 Space* dfsSpace = Gecode::dfs(ownBest->workingSpace);
00262 delete ownBest->workingSpace;
00263 ownBest->workingSpace = dfsSpace;
00264 }
00265 copy->constrain(*ownBest->workingSpace);
00266 }
00267 if (copy->status() == SS_FAILED) {
00268 delete copy;
00269 copy = NULL;
00270 }
00271 }
00272 }
00273 }
00274
00275 void
00276 SpaceNode::closeChild(bool hadFailures, bool hadSolutions) {
00277 setHasFailedChildren(hasFailedChildren() || hadFailures);
00278 setHasSolvedChildren(hasSolvedChildren() || hadSolutions);
00279
00280 bool allClosed = true;
00281 for (int i=getNumberOfChildren(); i--;) {
00282 if (static_cast<SpaceNode*>(getChild(i))->isOpen()) {
00283 allClosed = false;
00284 break;
00285 }
00286 }
00287
00288 if (allClosed) {
00289 setHasOpenChildren(false);
00290 for (unsigned int i=0; i<getNumberOfChildren(); i++)
00291 setHasSolvedChildren(hasSolvedChildren() ||
00292 static_cast<SpaceNode*>(getChild(i))->hasSolvedChildren());
00293 SpaceNode* p = static_cast<SpaceNode*>(getParent());
00294 if (p != NULL) {
00295 delete copy;
00296 copy = NULL;
00297 p->closeChild(hasFailedChildren(), hasSolvedChildren());
00298 }
00299 } else {
00300
00301 if (hadSolutions) {
00302 setHasSolvedChildren(true);
00303 SpaceNode* p = getParent();
00304 while (p != NULL && !p->hasSolvedChildren()) {
00305 p->setHasSolvedChildren(true);
00306 p = p->getParent();
00307 }
00308 }
00309 if (hadFailures) {
00310 SpaceNode* p = getParent();
00311 while (p != NULL && !p->hasFailedChildren()) {
00312 p->setHasFailedChildren(true);
00313 p = p->getParent();
00314 }
00315 }
00316 }
00317
00318 }
00319
00320 SpaceNode::SpaceNode(Space* root)
00321 : workingSpace(root), ownBest(NULL) {
00322 desc.branch = NULL;
00323 if (root == NULL) {
00324 setStatus(FAILED);
00325 setHasSolvedChildren(false);
00326 setHasFailedChildren(true);
00327 setNumberOfChildren(0);
00328 copy = root;
00329 return;
00330 }
00331 if (!root->failed())
00332 copy = root->clone();
00333 else
00334 copy = root;
00335 setStatus(UNDETERMINED);
00336 setHasSolvedChildren(false);
00337 setHasFailedChildren(false);
00338 }
00339
00340 SpaceNode::~SpaceNode(void) {
00341 if(getStatus() == SPECIAL)
00342 delete desc.special;
00343 else if (getStatus() == STEP)
00344 delete desc.step;
00345 else
00346 delete desc.branch;
00347 delete copy;
00348 delete workingSpace;
00349 }
00350
00351
00352 int
00353 SpaceNode::getNumberOfChildNodes(NodeAllocator& na,
00354 BestNode* curBest, Statistics& stats,
00355 int c_d, int a_d) {
00356 int kids = 0;
00357 if (isUndetermined()) {
00358 stats.undetermined--;
00359 acquireSpace(curBest, c_d, a_d);
00360 switch (workingSpace->status(stats)) {
00361 case SS_FAILED:
00362 {
00363 purge();
00364 kids = 0;
00365 setHasOpenChildren(false);
00366 setHasSolvedChildren(false);
00367 setHasFailedChildren(true);
00368 setStatus(FAILED);
00369 stats.failures++;
00370
00371 SpaceNode* p = getParent();
00372 if (p != NULL)
00373 p->closeChild(true, false);
00374 }
00375 break;
00376 case SS_SOLVED:
00377 {
00378
00379 (void) workingSpace->description();
00380 kids = 0;
00381 setStatus(SOLVED);
00382 setHasOpenChildren(false);
00383 setHasSolvedChildren(true);
00384 setHasFailedChildren(false);
00385 stats.solutions++;
00386 if (curBest != NULL) {
00387 curBest->s = this;
00388 }
00389 SpaceNode* p = getParent();
00390 if (p != NULL)
00391 p->closeChild(false, true);
00392 }
00393 break;
00394 case SS_BRANCH:
00395 desc.branch = workingSpace->description();
00396 kids = desc.branch->alternatives();
00397 setHasOpenChildren(true);
00398 setStatus(BRANCH);
00399 stats.choices++;
00400 stats.undetermined += kids;
00401 break;
00402 }
00403 static_cast<VisualNode*>(this)->changedStatus();
00404 setNumberOfChildren(kids);
00405 for (int i=kids; i--;) {
00406 setChild(i, new (na) VisualNode());
00407 }
00408 } else {
00409 kids = getNumberOfChildren();
00410 }
00411 return kids;
00412 }
00413
00414 int
00415 SpaceNode::getNoOfOpenChildren(void) {
00416 if (!hasOpenChildren())
00417 return 0;
00418 int noOfOpenChildren = 0;
00419 for (int i=getNumberOfChildren(); i--;)
00420 noOfOpenChildren += (static_cast<SpaceNode*>(getChild(i))->isOpen());
00421 return noOfOpenChildren;
00422 }
00423
00424 }}
00425
00426