Alps  2.0.2
AlpsSubTree.h
Go to the documentation of this file.
1 /*===========================================================================*
2  * This file is part of the Abstract Library for Parallel Search (ALPS). *
3  * *
4  * ALPS is distributed under the Eclipse Public License as part of the *
5  * COIN-OR repository (http://www.coin-or.org). *
6  * *
7  * Authors: *
8  * *
9  * Yan Xu, Lehigh University *
10  * Aykut Bulut, Lehigh University *
11  * Ted Ralphs, Lehigh University *
12  * *
13  * Conceptual Design: *
14  * *
15  * Yan Xu, Lehigh University *
16  * Ted Ralphs, Lehigh University *
17  * Laszlo Ladanyi, IBM T.J. Watson Research Center *
18  * Matthew Saltzman, Clemson University *
19  * *
20  * *
21  * Copyright (C) 2001-2023, Lehigh University, Yan Xu, Aykut Bulut, and *
22  * Ted Ralphs. *
23  * All Rights Reserved. *
24  *===========================================================================*/
25 
26 
27 #ifndef AlpsSubTree_h_
28 #define AlpsSubTree_h_
29 
30 #include <cassert>
31 #include <list>
32 
33 #include "CoinError.hpp"
34 #include "CoinSort.hpp"
35 
36 #include "AlpsSearchStrategy.h"
37 #include "AlpsKnowledge.h"
38 #include "AlpsNodePool.h"
39 #include "AlpsPriorityQueue.h"
40 #include "AlpsTreeNode.h"
41 
43 
44 //#############################################################################
45 
51 class AlpsSubTree : public AlpsKnowledge {
52 
53 protected:
54 
57 
60 
63 
65  AlpsSearchStrategy<AlpsTreeNode*> * diveNodeRule_;
66 
69 
70  // /** The next index to be assigned to a new search tree node */
71  // AlpsNodeIndex_t nextIndex_;
72 
76 
78  double quality_;
79 
80 protected:
81 
88  void removeDeadNodes(AlpsTreeNode*& node);
89 
91  void replaceNode(AlpsTreeNode* oldNode, AlpsTreeNode* newNode);
92 
96  void fathomAllNodes();
97 
98 public:
99 
101  AlpsSubTree();
102 
105 
107  virtual ~AlpsSubTree();
108 
109 public:
110 
112  inline AlpsTreeNode* activeNode() { return activeNode_; }
113 
116  { activeNode_ = activeNode; }
117 
119  void createChildren(AlpsTreeNode* parent,
120  std::vector< CoinTriple<AlpsNodeDesc*, AlpsNodeStatus,
121  double> >& children,
122  AlpsNodePool *kidNodePool = NULL);
123 
128  inline AlpsTreeNode* getRoot() const { return root_; }
129 
131  inline void setRoot(AlpsTreeNode* r) { root_ = r; }
132 
134  inline AlpsNodePool* nodePool() { return nodePool_; }
135 
138 
140  inline void setNodePool(AlpsNodePool* np) {
141  if (nodePool_ != NULL) {
142  delete nodePool_;
143  nodePool_ = NULL;
144  }
145  nodePool_ = np;
146  }
147 
149  inline void changeNodePool(AlpsNodePool* np) {
150  if (nodePool_ != NULL) {
151  // Remove all elements first.
152  nodePool_->clear();
153  // Delete an empty pool.
154  assert(nodePool_->hasKnowledge() == false);
155  delete nodePool_;
156  nodePool_ = NULL;
157  }
158  nodePool_ = np;
159  }
160 
162  double getBestKnowledgeValue() const;
163 
165  AlpsTreeNode *getBestNode() const;
166 
168  inline double getQuality() const { return quality_; }
169 
171  inline double getSolEstimate() const {
172  if (root_) {
173  return root_->getSolEstimate();
174  }
175  else {
176  return ALPS_OBJ_MAX;
177  };
178  }
179 
181  void incDiveDepth(int num=1) { diveDepth_ += num; }
182 
184  int getDiveDepth() { return diveDepth_; }
185 
187  void setDiveDepth(int num) { diveDepth_ = num; }
188 
191  double calculateQuality();
192 
193  /* Get the index of the next generated node and increment next index
194  by one.*/
195  int nextIndex();
196 
198  int getNextIndex() const;
199 
201  void setNextIndex(int next);
202 
204  int getNumNodes() const {
205  assert(nodePool_ && diveNodePool_);
206  int nn = 0;
207  if (activeNode_) {
210  ++nn;
211  }
212  }
213  return (nn + nodePool_->getNumKnowledges() +
215  }
216 
218  void setNodeSelection(AlpsSearchStrategy<AlpsTreeNode*>* nc) {
220  }
222 
225  AlpsSubTree* splitSubTree(int& returnSize, int size = 10);
226 
231  int nodeLimit,
232  double timeLimit,
233  int & numNodesProcessed, /* Output */
234  int & numNodesBranched, /* Output */
235  int & numNodesDiscarded, /* Output */
236  int & numNodesPartial, /* Output */
237  int & depth); /* Output */
238 
244  AlpsReturnStatus exploreUnitWork(bool leaveAsIt,
245  int unitWork,
246  double unitTime,
247  AlpsExitStatus & solStatus,/*not for parallel*/
248  int & numNodesProcessed, /* Output */
249  int & numNodesBranched, /* Output */
250  int & numNodesDiscarded, /* Output */
251  int & numNodesPartial, /* Output */
252  int & depth, /* Output */
253  bool & betterSolution); /* Output */
254 
257  virtual int rampUp(int minNumNodes,
258  int requiredNumNodes,
259  int& depth,
260  AlpsTreeNode* root = NULL);
261 
263  using AlpsKnowledge::encode;
264  // Encode this into the given AlpsEncoded object.
265  virtual AlpsReturnStatus encode(AlpsEncoded * encoded) const;
266  // Decode the given AlpsEncoded object into a new object and return a
267  // pointer to it.
268  virtual AlpsKnowledge * decode(AlpsEncoded & encoded) const;
270  virtual AlpsReturnStatus decodeToSelf(AlpsEncoded & encoded);
271 
274  virtual AlpsSubTree* newSubTree() const {
275  return new AlpsSubTree(broker_);
276  }
277 
279  void clearNodePools() {
280  if (nodePool_) {
281  nodePool_->clear();
282  }
283  if (diveNodePool_) {
284  diveNodePool_->clear();
285  }
286  }
287 
290  root_ = NULL;
291  activeNode_ = NULL;
292  }
293 
295  bool doDive() {
296  return true;
297  }
298 
300  void reset() {
301  // Move nodes in diving pool to normal pool.
302  AlpsTreeNode *tempNode = NULL;
303  while (diveNodePool_->getNumKnowledges() > 0) {
304  tempNode = dynamic_cast<AlpsTreeNode *>
305  (diveNodePool_->getKnowledge().first);
307  nodePool_->addKnowledge(tempNode, tempNode->getQuality());
308  }
309 
310  if (activeNode_) {
312  activeNode_ = NULL;
313  }
314 
315  diveDepth_ = 0;
316  }
317 
318 };
319 #endif
320 
321 //#############################################################################
322 // The way to create children:
323 //-----------------------------------------------------------------------------
324 // In AlpsSubTree::exploreSubTree(root)
325 // If (pregnant)
326 // => KnapTreeNode::branch()
327 // => AlpsSubTree::createChildren(...) {
328 // AlpsTreeNode::setNumChildren(...) (allocate memory if not);
329 // KnapTreeNode:: createNewTreeNode(...);
330 // AlpsSubTree::setChildren;
331 // AlspSubTree::setStatus }
332 //#############################################################################
333 
334 //#############################################################################
335 // The way to remove nodes:
336 //-----------------------------------------------------------------------------
337 // In AlpsSubTree::exploreSubTree(root)
338 // If (fathomed)
339 // => AlpsSubTree::removeDeadNode(node) {
340 // AlpsTreeNode::removeChild(node) {
341 // AlpsTreeNode::removeDescendants();
342 // }
343 // Check whether parent has children;
344 // if (yes), recursively removeDeadNode(parent)
345 //#############################################################################
AlpsTreeNode::getStatus
AlpsNodeStatus getStatus() const
Definition: AlpsTreeNode.h:160
AlpsSubTree::nodePool
AlpsNodePool * nodePool()
Access the node pool.
Definition: AlpsSubTree.h:134
AlpsSubTree::splitSubTree
AlpsSubTree * splitSubTree(int &returnSize, int size=10)
The function split the subtree and return a subtree of the specified size or available size.
AlpsSubTree::replaceNode
void replaceNode(AlpsTreeNode *oldNode, AlpsTreeNode *newNode)
This function replaces oldNode with newNode in the tree.
AlpsKnowledge.h
AlpsSubTree::setActiveNode
void setActiveNode(AlpsTreeNode *activeNode)
Set pointer to active node.
Definition: AlpsSubTree.h:115
AlpsSubTree::getNextIndex
int getNextIndex() const
Get the index of the next generated node.
AlpsSubTree::activeNode_
AlpsTreeNode * activeNode_
This is the node that is currently being processed.
Definition: AlpsSubTree.h:75
AlpsSubTree::decode
virtual AlpsKnowledge * decode(AlpsEncoded &encoded) const
Decode the given AlpsEncoded object into a new AlpsKnowledge object and return a pointer to it.
AlpsSubTree::setNextIndex
void setNextIndex(int next)
Set the index of the next generated node.
AlpsReturnStatus
AlpsReturnStatus
Definition: Alps.h:261
AlpsSubTree::changeNodePool
void changeNodePool(AlpsNodePool *np)
Set node pool.
Definition: AlpsSubTree.h:149
AlpsNodePool::getNumKnowledges
virtual int getNumKnowledges() const
Query the number of nodes in the node pool.
AlpsNodePool::popKnowledge
virtual void popKnowledge()
Remove the node with highest priority from the pool.
Definition: AlpsNodePool.h:82
AlpsKnowledge::broker_
AlpsKnowledgeBroker * broker_
Definition: AlpsKnowledge.h:66
AlpsNodeStatusBranched
@ AlpsNodeStatusBranched
Definition: Alps.h:202
AlpsNodeStatus
AlpsNodeStatus
The possible stati for the search nodes.
Definition: Alps.h:198
AlpsNodePool::clear
void clear()
Remove all the nodes in the pool (does not free memory).
Definition: AlpsNodePool.h:101
AlpsSubTree::getDiveDepth
int getDiveDepth()
Get dive depth.
Definition: AlpsSubTree.h:184
AlpsSubTree::incDiveDepth
void incDiveDepth(int num=1)
Increment dive depth.
Definition: AlpsSubTree.h:181
AlpsSubTree::diveNodeRule_
AlpsSearchStrategy< AlpsTreeNode * > * diveNodeRule_
Diving node comparing rule.
Definition: AlpsSubTree.h:65
AlpsEncoded
Definition: AlpsEncoded.h:64
AlpsSubTree::setRoot
void setRoot(AlpsTreeNode *r)
Set the root node of this subtree.
Definition: AlpsSubTree.h:131
AlpsSubTree::clearNodePools
void clearNodePools()
Remove nodes in pools in the subtree.
Definition: AlpsSubTree.h:279
AlpsNodeStatusFathomed
@ AlpsNodeStatusFathomed
Definition: Alps.h:203
AlpsSubTree::removeDeadNodes
void removeDeadNodes(AlpsTreeNode *&node)
The purpose of this method is to remove nodes that are not needed in the description of the subtree.
AlpsTreeNode.h
AlpsNodePool::getKnowledge
virtual std::pair< AlpsKnowledge *, double > getKnowledge() const
Get the node with highest priority. Doesn't remove it from the pool.
AlpsSubTree::getSolEstimate
double getSolEstimate() const
Get the estimated quality of this subtree.
Definition: AlpsSubTree.h:171
AlpsSubTree::setNodeSelection
void setNodeSelection(AlpsSearchStrategy< AlpsTreeNode * > *nc)
Set the node comparision rule.
Definition: AlpsSubTree.h:218
AlpsTreeNode
This class holds one node of the search tree.
Definition: AlpsTreeNode.h:52
AlpsSubTree::decodeToSelf
virtual AlpsReturnStatus decodeToSelf(AlpsEncoded &encoded)
Decode the given AlpsEncoded object into this.
AlpsSubTree::rampUp
virtual int rampUp(int minNumNodes, int requiredNumNodes, int &depth, AlpsTreeNode *root=NULL)
Generate required number (specified by a parameter) of nodes.
AlpsTreeNode::getQuality
double getQuality() const
Query/set the quality of the node.
Definition: AlpsTreeNode.h:207
AlpsSubTree::nullRootActiveNode
void nullRootActiveNode()
Set root and active node to null.
Definition: AlpsSubTree.h:289
AlpsSubTree::getQuality
double getQuality() const
Get the quality of this subtree.
Definition: AlpsSubTree.h:168
AlpsSubTree::getBestNode
AlpsTreeNode * getBestNode() const
Get the "best" node in the subtree.
AlpsSubTree::quality_
double quality_
A quantity indicating how good this subtree is.
Definition: AlpsSubTree.h:78
AlpsSubTree::calculateQuality
double calculateQuality()
Calcuate and return the quality of this subtree, which is measured by the quality of the specified nu...
AlpsNodeDesc
This is an abstract base class for subproblem data to be stored in a tree node.
Definition: AlpsNodeDesc.h:45
AlpsSubTree::getNumNodes
int getNumNodes() const
Return the number of nodes on this subtree.
Definition: AlpsSubTree.h:204
AlpsExitStatus
AlpsExitStatus
Definition: Alps.h:244
AlpsSubTree::doDive
bool doDive()
Check whether we should keep diving or not.
Definition: AlpsSubTree.h:295
AlpsSubTree::getBestKnowledgeValue
double getBestKnowledgeValue() const
Get the quality of the best node in the subtree.
AlpsSubTree::exploreSubTree
virtual AlpsReturnStatus exploreSubTree(AlpsTreeNode *root, int nodeLimit, double timeLimit, int &numNodesProcessed, int &numNodesBranched, int &numNodesDiscarded, int &numNodesPartial, int &depth)
Explore the subtree from root as the root of the subtree for given number of nodes or time,...
AlpsKnowledge
The abstract base class of Alps knowledges generated during the search.
Definition: AlpsKnowledge.h:63
AlpsSubTree::~AlpsSubTree
virtual ~AlpsSubTree()
Destructor.
ALPS_OBJ_MAX
#define ALPS_OBJ_MAX
Definition: Alps.h:288
AlpsKnowledgeBroker
The base class of knowledge broker class.
Definition: AlpsKnowledgeBroker.h:52
AlpsKnowledge::encode
AlpsEncoded * encode() const
Encode the content of this into an AlpsEncoded object and return a pointer to it.
AlpsNodePool::setNodeSelection
void setNodeSelection(AlpsSearchStrategy< AlpsTreeNode * > &compare)
Set strategy and resort heap.
AlpsPriorityQueue.h
AlpsNodePool
AlpsNodePool is used to store the nodes to be processed.
Definition: AlpsNodePool.h:43
AlpsSubTree::createChildren
void createChildren(AlpsTreeNode *parent, std::vector< CoinTriple< AlpsNodeDesc *, AlpsNodeStatus, double > > &children, AlpsNodePool *kidNodePool=NULL)
Create children nodes from the given parent node.
AlpsTreeNode::getSolEstimate
double getSolEstimate() const
Query/set the solution estimate of the node.
Definition: AlpsTreeNode.h:201
AlpsSubTree::root_
AlpsTreeNode * root_
The root of the sub tree.
Definition: AlpsSubTree.h:56
AlpsSubTree::activeNode
AlpsTreeNode * activeNode()
Get pointer to active node.
Definition: AlpsSubTree.h:112
AlpsSubTree::diveDepth_
int diveDepth_
Diving depth.
Definition: AlpsSubTree.h:68
AlpsNodePool::hasKnowledge
virtual bool hasKnowledge() const
Check whether there are still nodes in the node pool.
Definition: AlpsNodePool.h:67
AlpsSubTree::setDiveDepth
void setDiveDepth(int num)
Set dive depth.
Definition: AlpsSubTree.h:187
AlpsNodePool::addKnowledge
virtual void addKnowledge(AlpsKnowledge *node, double priority)
Add a node to node pool.
AlpsSubTree::nodePool_
AlpsNodePool * nodePool_
A node pool containing the leaf nodes awaiting processing.
Definition: AlpsSubTree.h:59
AlpsSubTree
This class contains the data pertaining to a particular subtree in the search tree.
Definition: AlpsSubTree.h:51
AlpsSearchStrategy.h
AlpsSubTree::nextIndex
int nextIndex()
AlpsSubTree::exploreUnitWork
AlpsReturnStatus exploreUnitWork(bool leaveAsIt, int unitWork, double unitTime, AlpsExitStatus &solStatus, int &numNodesProcessed, int &numNodesBranched, int &numNodesDiscarded, int &numNodesPartial, int &depth, bool &betterSolution)
Explore the subtree for certain amount of work/time.
AlpsSubTree::newSubTree
virtual AlpsSubTree * newSubTree() const
Create a AlpsSubtree object dynamically.
Definition: AlpsSubTree.h:274
AlpsSubTree::diveNodePool_
AlpsNodePool * diveNodePool_
A node pool used when diving.
Definition: AlpsSubTree.h:62
AlpsSubTree::getRoot
AlpsTreeNode * getRoot() const
Get the root node of this subtree.
Definition: AlpsSubTree.h:128
AlpsSubTree::fathomAllNodes
void fathomAllNodes()
Fathom all nodes on this subtree.
AlpsSubTree::setNodePool
void setNodePool(AlpsNodePool *np)
Set node pool.
Definition: AlpsSubTree.h:140
AlpsSubTree::reset
void reset()
Move nodes in node pool, null active node.
Definition: AlpsSubTree.h:300
AlpsNodePool.h
AlpsSubTree::diveNodePool
AlpsNodePool * diveNodePool()
Access the node pool.
Definition: AlpsSubTree.h:137
AlpsSubTree::AlpsSubTree
AlpsSubTree()
Default constructor.