this repo has no description
1/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ 2/* 3 * Main authors: 4 * Guido Tack <tack@gecode.org> 5 * 6 * Copyright: 7 * Guido Tack, 2006 8 * 9 * This file is part of Gecode, the generic constraint 10 * development environment: 11 * http://www.gecode.org 12 * 13 * Permission is hereby granted, free of charge, to any person obtaining 14 * a copy of this software and associated documentation files (the 15 * "Software"), to deal in the Software without restriction, including 16 * without limitation the rights to use, copy, modify, merge, publish, 17 * distribute, sublicense, and/or sell copies of the Software, and to 18 * permit persons to whom the Software is furnished to do so, subject to 19 * the following conditions: 20 * 21 * The above copyright notice and this permission notice shall be 22 * included in all copies or substantial portions of the Software. 23 * 24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 28 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 29 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 30 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 31 * 32 */ 33 34#ifndef GECODE_GIST_SPACENODE_HH 35#define GECODE_GIST_SPACENODE_HH 36 37#include <gecode/gist/node.hh> 38#include <gecode/kernel.hh> 39 40namespace Gecode { namespace Gist { 41 42 /** \brief Status of nodes in the search tree 43 */ 44 enum NodeStatus { 45 SOLVED, ///< Node representing a solution 46 FAILED, ///< Node representing failure 47 BRANCH, ///< Node representing a branch 48 UNDETERMINED, ///< Node that has not been explored yet 49 STOP, ///< Node representing stop point 50 UNSTOP, ///< Node representing ignored stop point 51 }; 52 53 static const unsigned int FIRSTBIT = 24; //< First free bit in status word 54 static const unsigned int STATUSMASK = 7<<20; //< Mask for accessing status 55 static const unsigned int MAXDISTANCE = (1<<20)-1; //< Maximum representable distance 56 static const unsigned int DISTANCEMASK = (1<<20)-1; //< Mask for accessing distance 57 58 /// %Statistics about the search tree 59 class Statistics : public StatusStatistics { 60 public: 61 /// Number of solutions 62 int solutions; 63 /// Number of failures 64 int failures; 65 /// Number of choice nodes 66 int choices; 67 /// Number of open, undetermined nodes 68 int undetermined; 69 /// Maximum depth of the tree 70 int maxDepth; 71 72 /// Constructor 73 Statistics(void) 74 : solutions(0), failures(0), choices(0), undetermined(1), maxDepth(0) {} 75 }; 76 77 class SpaceNode; 78 79 /// \brief Static reference to the currently best space 80 class BestNode { 81 public: 82 /// The currently best node found, or nullptr 83 SpaceNode* s; 84 /// Constructor 85 BestNode(SpaceNode* s0); 86 }; 87 88 /// \brief A node of a search tree of %Gecode spaces 89 class SpaceNode : public Node { 90 protected: 91 /** \brief A copy used for recomputation, or nullptr 92 * 93 * If the copy is marked, it is a working copy, i.e., 94 * it does not have to be kept for recomputation. 95 */ 96 Space* copy; 97 protected: 98 const Choice* choice; 99 100 /** \brief Status of the node 101 * 102 * If the node has a working copy, the first 20 bits encode the distance 103 * to the closest copy. The next 5 bits encode the NodeStatus, and the 104 * remaining bits are used by the VisualNode class for further flags. 105 */ 106 unsigned int nstatus; 107 108 /// Set distance from copy 109 void setDistance(unsigned int d); 110 111 /// Return distance from copy 112 unsigned int getDistance(void) const; 113 114 /// Set status flag 115 void setFlag(int flag, bool value); 116 117 /// Return status flag 118 bool getFlag(int flag) const; 119 120 /// Flags for SpaceNodes 121 enum SpaceNodeFlags { 122 HASOPENCHILDREN = FIRSTBIT, 123 HASFAILEDCHILDREN, 124 HASSOLVEDCHILDREN 125 }; 126 /// Last bit used for SpaceNode flags 127 static const int LASTBIT = HASSOLVEDCHILDREN; 128 129 private: 130 /// Set whether the node has children that are not fully explored 131 void setHasOpenChildren(bool b); 132 /// Set whether the subtree of this node is known to contain failure 133 void setHasFailedChildren(bool b); 134 /// Set whether the subtree of this node is known to contain solutions 135 void setHasSolvedChildren(bool b); 136 137 /// Recompute workingSpace from a copy higher up, return distance to copy 138 int recompute(NodeAllocator& na, 139 BestNode* curBest, int c_d, int a_d); 140 141 /// Book-keeping of open children 142 void closeChild(const NodeAllocator& na, 143 bool hadFailures, bool hadSolutions); 144 protected: 145 /// Set status to \a s 146 void setStatus(NodeStatus s); 147 /// Acquire working space, either from parent or by recomputation 148 void acquireSpace(NodeAllocator& na, 149 BestNode* curBest, int c_d, int a_d); 150 public: 151 /// Construct node with parent \a p 152 SpaceNode(int p); 153 /// Construct root node from Space \a root and branch-and-bound object \a better 154 SpaceNode(Space* root); 155 156 /// Return working space. Receiver must delete the space. 157 Space* getSpace(NodeAllocator& na, 158 BestNode* curBest, int c_d, int a_d); 159 160 /// Return working space (if present). 161 const Space* getWorkingSpace(void) const; 162 163 /// Clear working space and copy (if present and this is not the root). 164 void purge(const NodeAllocator& na); 165 166 /// Free allocated memory 167 void dispose(void); 168 169 /// Return whether this node is the currently best solution 170 bool isCurrentBest(BestNode* curBest); 171 172 /** \brief Compute and return the number of children 173 * 174 * On a node whose status is already determined, this function 175 * just returns the number of children. On an undetermined node, 176 * it first acquires a Space (possibly through recomputation), and 177 * then asks for its status. If the space is solved or failed, the 178 * node's status will be set accordingly, and 0 will be returned. 179 * Otherwise, the status is SS_BRANCH, and as many new children will 180 * be created as the branch has alternatives, and the number returned. 181 */ 182 int getNumberOfChildNodes(NodeAllocator& na, 183 BestNode* curBest, 184 Statistics& stats, 185 int c_d, int a_d); 186 187 /// Return current status of the node 188 NodeStatus getStatus(void) const; 189 190 /// Return whether this node still has open children 191 bool isOpen(void); 192 /// Return whether the subtree of this node has any failed children 193 bool hasFailedChildren(void); 194 /// Return whether the subtree of this node has any solved children 195 bool hasSolvedChildren(void); 196 /// Return whether the subtree of this node has any open children 197 bool hasOpenChildren(void); 198 /// Return number of open children 199 int getNoOfOpenChildren(const NodeAllocator& na); 200 /// Set number of open children to \a n 201 void setNoOfOpenChildren(int n); 202 /// Return whether the node has a copy 203 bool hasCopy(void); 204 /// Return whether the node has a working space 205 bool hasWorkingSpace(void); 206 207 /// Return alternative number of this node 208 int getAlternative(const NodeAllocator& na) const; 209 /// Return choice of this node 210 const Choice* getChoice(void); 211 }; 212 213}} 214 215#endif 216 217// STATISTICS: gist-any