SpaceNode.java
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 package org.gecode.gist;
00029
00030 import java.util.*;
00031 import org.gecode.*;
00032
00033 public abstract class SpaceNode extends VisualNode {
00034
00035 class Branch {
00036 int alternative;
00037 BranchingDesc desc;
00038 Space ownBest = null;
00039 Branch(int a, BranchingDesc d) {
00040 alternative = a;
00041 desc = d;
00042 }
00043 Branch(int a, BranchingDesc d, Space best) {
00044 alternative = a;
00045 desc = d;
00046 ownBest = best;
00047 }
00048 }
00049
00050 protected Statistics stats;
00051
00052 private Space copy;
00053 public Space workingSpace;
00054
00055 private BranchingDesc desc;
00056 private int alternative;
00057 private NodeStatus status = NodeStatus.UNDETERMINED;
00058
00059 public BestSpace curBest = null;
00060 private Space ownBest = null;
00061
00062 private int noOfOpenChildren = 0;
00063 private boolean hasFailedChildren = false;
00064 private boolean hasSolvedChildren = false;
00065
00066 public SpaceNode(int alt, Statistics theStats) {
00067 super();
00068 alternative = alt;
00069 stats = theStats;
00070 }
00071
00072 public SpaceNode(int alt, BestSpace best, Statistics theStats) {
00073 super();
00074 alternative = alt;
00075 curBest = best;
00076 stats = theStats;
00077 }
00078
00079 public SpaceNode(Space root, Statistics theStats) {
00080 super();
00081 workingSpace = root;
00082 if (!root.failed()) {
00083 copy = root.cloneSpace();
00084 } else {
00085 copy = root;
00086 }
00087 stats = theStats;
00088 }
00089
00090 public void initCurBest(BestSpace c) {
00091 curBest = c;
00092 }
00093
00094 protected int recompute() {
00095 int rdist = 0;
00096 if (workingSpace == null) {
00097 SpaceNode curNode = this;
00098 Stack<Branch> stack = new Stack<Branch>();
00099
00100 while (curNode.copy==null) {
00101 SpaceNode parent = (SpaceNode)curNode.getParent();
00102 Branch b;
00103 if (curBest != null) {
00104 b = new Branch(curNode.alternative, parent.desc, curNode.ownBest);
00105 } else {
00106 b = new Branch(curNode.alternative, parent.desc);
00107 }
00108 stack.push(b);
00109 curNode = parent;
00110 rdist++;
00111 }
00112 Space curSpace = curNode.copy.cloneSpace();
00113
00114 Space lastBest = null;
00115 SpaceNode middleNode = curNode;
00116 int curDist = 0;
00117 while (!stack.empty()) {
00118 if (Config.a_d() >= 0 &&
00119 curDist > Config.a_d() &&
00120 curDist == rdist / 2) {
00121 middleNode.copy = curSpace.cloneSpace();
00122 }
00123 Branch b = (Branch)stack.pop();
00124 curSpace.commit(b.desc, b.alternative);
00125
00126 if (b.ownBest != lastBest && b.ownBest != null) {
00127 curSpace.constrain(b.ownBest);
00128 lastBest = b.ownBest;
00129 }
00130 curDist++;
00131 middleNode = (SpaceNode) middleNode.getChild(b.alternative);
00132 }
00133 workingSpace = curSpace;
00134 }
00135 return rdist;
00136 }
00137
00138 private Space donateSpace(int alt, Space ownBest) {
00139 Space ret = workingSpace;
00140 if (ret != null) {
00141 workingSpace = null;
00142 ret.commit(desc, alt);
00143
00144 if (ownBest != null) {
00145 ret.constrain(ownBest);
00146 }
00147 }
00148 return ret;
00149 }
00150
00151 private Space checkLAO(int alt, Space ownBest) {
00152 Space ret = null;
00153 if (copy != null && noOfOpenChildren == 1 && getParent() != null) {
00154
00155 ret = copy;
00156 copy = null;
00157 ret.commit(desc, alt);
00158
00159 if (ownBest != null) {
00160 ret.constrain(ownBest);
00161 }
00162 }
00163 return ret;
00164 }
00165
00166 protected void acquireSpace() {
00167 SpaceNode p = (SpaceNode) getParent();
00168 if (status==Undetermined && curBest != null && ownBest == null &&
00169 p != null && curBest.s != p.ownBest) {
00170 ownBest = curBest.s;
00171 }
00172 if (workingSpace == null && p != null)
00173 workingSpace = p.donateSpace(alternative, ownBest);
00174 if (workingSpace == null) {
00175 if ( recompute() > Config.mrd() && Config.mrd() >= 0 &&
00176 workingSpace.status(new long[1]) == SpaceStatus.SS_BRANCH ) {
00177 copy = workingSpace.cloneSpace();
00178 }
00179 }
00180 if (copy == null && p != null) {
00181 copy = p.checkLAO(alternative, ownBest);
00182 }
00183 }
00184
00185 public Space getSpace() {
00186 acquireSpace();
00187 if (workingSpace.status(new long[1]) != SpaceStatus.SS_FAILED) {
00188 return workingSpace.cloneSpace();
00189 }
00190 return workingSpace;
00191 }
00192
00193 private void solveUp() {
00194 SpaceNode p = (SpaceNode)getParent();
00195 hasSolvedChildren = true;
00196 if (p != null && !p.hasSolvedChildren)
00197 p.solveUp();
00198 }
00199 void closeChild(boolean hadFailures, boolean hadSolutions) {
00200 noOfOpenChildren--;
00201 hasFailedChildren = hasFailedChildren || hadFailures;
00202 hasSolvedChildren = hasSolvedChildren || hadSolutions;
00203 SpaceNode p = (SpaceNode)getParent();
00204 if (noOfOpenChildren == 0) {
00205 stats.close();
00206 if (p != null)
00207 p.closeChild(hasFailedChildren, hasSolvedChildren);
00208 } else if (hadSolutions) {
00209 solveUp();
00210 }
00211 }
00212
00213 public void hideFailed() {
00214 DefaultNodeCursor cursor =
00215 new DefaultNodeCursor(this) {
00216 public boolean mayMoveDownwards() {
00217 SpaceNode snode = (SpaceNode) getCurrentNode();
00218 return
00219 super.mayMoveDownwards() &&
00220 (snode.hasSolvedChildren ||
00221 snode.noOfOpenChildren > 0);
00222 }
00223 public void processCurrentNode() {
00224 SpaceNode snode = (SpaceNode) getCurrentNode();
00225 if (snode.getStatus() == NodeStatus.BRANCH &&
00226 !snode.hasSolvedChildren &&
00227 snode.noOfOpenChildren == 0)
00228 snode.hide();
00229 }
00230 };
00231 PreOrderNodeVisitor visitor = new PreOrderNodeVisitor(cursor);
00232 visitor.run();
00233 }
00234
00235 public Iterator reversedChildrenIterator() {
00236
00237 int numberNotNeeded = getNumberOfChildNodes();
00238 return super.reversedChildrenIterator();
00239 }
00240
00241 public int getNumberOfChildNodes() {
00242 int kids = getNumberOfChildren();
00243 if (kids == -1) {
00244 stats.newDetermined();
00245 acquireSpace();
00246 status = NodeStatus.valueOf(workingSpace.status());
00247 switch (status) {
00248 case FAILED:
00249 workingSpace.delete();
00250 workingSpace = null;
00251 kids = 0;
00252 hasSolvedChildren = false;
00253 hasFailedChildren = true;
00254 stats.newFailure();
00255 stats.newDepth(getDepth());
00256 if (getParent() != null)
00257 ((SpaceNode)getParent()).closeChild(true,false);
00258 break;
00259 case SOLVED:
00260 kids = 0;
00261 hasSolvedChildren = true;
00262 hasFailedChildren = false;
00263 stats.newSolution();
00264 stats.newDepth(getDepth());
00265 if (curBest != null) {
00266 curBest.s = workingSpace.cloneSpace();
00267 }
00268 if (getParent() != null)
00269 ((SpaceNode)getParent()).closeChild(false,true);
00270 break;
00271 case BRANCH:
00272 desc = workingSpace.description();
00273 kids = (int) desc.alternatives();
00274 stats.newChoice();
00275 stats.newOpen();
00276 stats.newUndetermined(kids);
00277 stats.newDepth(getDepth() + 1);
00278 break;
00279 }
00280 setNumberOfChildren(kids);
00281 noOfOpenChildren = kids;
00282 dirtyUp();
00283 for (int i = 0; i < kids; i++) {
00284 SpaceNode child = createChild(i);
00285 setNextChild(i, child);
00286 child.dirtyUp();
00287 }
00288 }
00289 return kids;
00290 }
00291
00292 public NodeStatus getStatus() {
00293 return status;
00294 }
00295 public void setStatus(NodeStatus s) {
00296 status = s;
00297 }
00298
00299 public boolean isOpen() {
00300 return status==Undetermined || noOfOpenChildren > 0;
00301 }
00302
00303 public boolean hasFailedChildren() {
00304 return hasFailedChildren;
00305 }
00306 public boolean hasSolvedChildren() {
00307 return hasSolvedChildren;
00308 }
00309
00310 protected abstract SpaceNode createChild(int i);
00311
00312 protected int getAlternative() {
00313 return alternative;
00314 }
00315 }