SmiScenarioTree.hpp
Go to the documentation of this file.
1 // Copyright (C) 2003, International Business Machines
2 // Corporation and others. All Rights Reserved.
3 #ifndef SmiScenarioTree_H
4 #define SmiScenarioTree_H
5 
12 #include <vector>
13 #include <map>
14 #include <iostream>
15 #include <cassert>
16 
17 #include "CoinPragma.hpp"
18 
26 template<class T>
27 class SmiTreeNode {
28  //friend void SmiTreeNodeUnitTest();
29 public:
30 
31  typedef std::map<int, SmiTreeNode<T>*> child_label_map;
32 
33  bool hasParent() {
34  return (parent_ != NULL);
35  }
36  bool hasChild() {
37  return (child_ != NULL);
38  }
39  bool hasSibling() {
40  return (sibling_ != NULL);
41  }
42 
44  return parent_;
45  }
47  return child_;
48  }
50  return sibling_;
51  }
52 
53  void setLastChildLabel(int label) {
54  child_labels_.insert(std::make_pair(label, this->getChild()));
55  }
56 
58 
59  /*
60  //AJK debug code
61  child_label_map::iterator begpos = child_labels_.begin();
62  child_label_map::iterator endpos = child_labels_.end();
63  while(begpos!=endpos)
64  {
65  printf(" found label %d \n",begpos->first);
66  ++begpos;
67  }
68  */
69  typename child_label_map::iterator pos = child_labels_.find(n);
70  if (pos != child_labels_.end())
71  return pos->second;
72  else
73  return NULL;
74  }
75 
76  int depth() {
77  return depth_;
78  }
79  int numChildren() {
80  return nchild_;
81  }
82  int scenario() {
83  return scen_;
84  }
85  void setScenario(int s) {
86  scen_ = s;
87  }
88 
89  // Returns new child node with cd, linked in the tree
91  SmiTreeNode<T> *c = new SmiTreeNode(cd);
92 
93  c->parent_ = this;
94  c->depth_ = depth_ + 1;
95  c->sibling_ = child_;
96  c->scen_ = scenario;
97  nchild_++;
98  child_ = c;
99  return c;
100  }
101 
102  std::vector<SmiTreeNode<T> *> *getChildren() {
103  SmiTreeNode<T> *pnode = this;
104  int i = this->numChildren();
105  if (i == 0) {
106  return NULL;
107  }
108  std::vector<SmiTreeNode<T> *> *vec = new std::vector<SmiTreeNode<T> *> (i);
109  (*vec)[--i] = pnode = pnode->getChild();
110  while (i > 0)
111  (*vec)[--i] = pnode = pnode->getSibling();
112  return vec;
113  }
114 
116  return ptr_;
117  }
118 
119  //--------------------------------------------------------------------------
122  SmiTreeNode<T> () {
124  parent_ = NULL;
125  child_ = NULL;
126  sibling_ = NULL;
127  nchild_ = 0;
128  depth_ = 0;
129  scen_ = -1;
130  }
131 
134  parent_ = NULL;
135  child_ = NULL;
136  sibling_ = NULL;
137  nchild_ = 0;
138  depth_ = 0;
139  ptr_ = p;
140  scen_ = -1;
141  }
142 
144 
146  delete sibling_;
147  delete child_;
148  }
149 
151 
152 protected:
153 
155  child_ = c;
156  }
158  sibling_ = s;
159  }
161  return parent_;
162  }
164  return child_;
165  }
167  return sibling_;
168  }
169 
170 private:
174  int scen_;
175  int nchild_;
176  int depth_;
177  T ptr_;
179 
180 };
181 
182 //#############################################################################
188 void SmiTreeNodeUnitTest();
189 
190 /*TODO: split this class into two classes
191  * 1) SmiScenarioTree
192  * 2) SmiLabelledTree
193  */
194 
195 template<class T>
197  //friend void SmiScenarioTreeUnitTest();
198 public:
199 
200  //---------------------------------------------------------------------------
203 
204 
206  typename std::vector<T>::iterator treeBegin() {
207  return node_data.begin();
208  }
210  typename std::vector<T>::iterator treeEnd() {
211  return node_data.end();
212  }
214  std::vector<T> &wholeTree() {
215  return node_data;
216  }
217 
221  typename std::vector<T>::iterator scenBegin(int s) {
222  getScenario(s);
223  return scen_data.begin();
224  }
225 
226  typename std::vector<T>::iterator scenEnd(int s) {
227  getScenario(s);
228  return scen_data.begin() + leaf_[s]->depth() + 1;
229  }
230 
231  //---------------------------------------------------------------------------
234 
237  return root_;
238  }
239 
242  return leaf_[scn];
243  }
244 
246  SmiTreeNode<T> *find(unsigned int scenario, int stage) {
247  assert (scenario < leaf_.size());
248  SmiTreeNode<T> * n = leaf_[scenario];
249  assert (stage < n->depth() + 1);
250  while (stage < n->depth())
251  n = n->getParent();
252  return n;
253  }
254 
257  return (int) leaf_.size();
258  }
259 
261  SmiTreeNode<T> *find(std::vector<int> &label) {
262 
263  assert(label.size()>0);
264  SmiTreeNode<T> *n = root_, *next;
265  unsigned int i = 1;
266  while ((i < label.size()) && (next = n->getChildByLabel(label[i]))) {
267  ++i;
268  n = next;
269  }
270  return n;
271  }
272 
274  SmiTreeNode<T> *find(int *label, unsigned int sz) {
275 
276  assert(sz>0);
277  SmiTreeNode<T> *n = root_, *next;
278  if (!n)
279  return n;
280  unsigned int i = 0;
281  while ((i < sz) && (next = n->getChildByLabel(label[i]))) {
282  ++i;
283  n = next;
284  }
285  return n;
286  }
287 
289  std::vector<T> &getScenario(int scenario) {
290  assert (scenario < (int) leaf_.size());
291  SmiTreeNode<T> * n = leaf_[scenario];
292 
293  //if ( n->getDataPtr()==scen_data[n->depth()] ) return scen_data;
294  //Christian: Why is this necessary? Reason: Number of Stages places should be readily available in the vector, if this is not already the case, do it..
295  //int ns = n->depth() + 1 - scen_data.size();
296  //for (int j = 0; j < ns; j++)
297  // scen_data.push_back(n->getDataPtr());
298 
299  //Christian: TODO: Why not change this so, that it looks better? i.e. i-- and i= n->depth(); and i >= 0?
300  //Christian: TODO: Think about changing container from vector to deque or list..
301  int i = n->depth() + 1;
302  scen_data.resize(i,n->getDataPtr()); //Maybe a call to capacity should do it too.. ?! TODO
303  while (i > 0) {
304  scen_data[--i] = n->getDataPtr();
305  n = n->getParent();
306  }
307  return scen_data;
308  }
309 
311 
312  //---------------------------------------------------------------------------
322  int addPathtoLeaf(int brscenario, int stage, std::vector<T> &pathdata,
323  unsigned int start = 0) {
324  SmiTreeNode<T> *parent = NULL;
325  int scenario = static_cast<int>(leaf_.size());
326  if (scenario)
327  parent = find(brscenario, stage);
328 
329  parent = addNodesToTree(parent, scenario, pathdata, start);
330 
331  if (pathdata.size()) {
332  leaf_.push_back(parent);
333  }
334  return static_cast<int>(leaf_.size()) - 1;
335 
336  }
337 
339  void setChildLabels(SmiTreeNode<T> *n, std::vector<int> labels) {
340  int t = n->depth();
341  while (n->hasChild()) {
342  n->setLastChildLabel(labels[++t]);
343  n = n->getChild();
344  }
345  }
346 
353  int addPathtoLeaf(std::vector<int> &labels, std::vector<T> &pathdata) {
354  SmiTreeNode<T> *parent = NULL;
355  int scenario = static_cast<int>(leaf_.size());
356  if (scenario)
357  parent = find(labels);
358 
359  unsigned int i = 0;
360  if (parent)
361  i = parent->depth() + 1;
362 
363  parent = addNodesToTree(parent, scenario, pathdata, i);
364 
365  if (pathdata.size()) {
366  leaf_.push_back(parent);
367  }
368  return static_cast<int>(leaf_.size()) - 1;
369 
370  }
371 
373  std::vector<T> &pathdata, int start) {
374 
375  for (unsigned int i = start; i < pathdata.size(); ++i) {
376  if (parent) {
377  parent = parent->addChild(*&pathdata[i], scenario);
378  } else {
379  parent = root_ = new SmiTreeNode<T> (*&pathdata[0]);
380  root_->setScenario(scenario);
381  }
382  // add data to full node_data array
383  node_data.push_back(*&pathdata[i]);
384  }
385 
386  return parent;
387  }
389  //--------------------------------------------------------------------------
392  SmiScenarioTree<T> () :
394  leaf_(0), root_(NULL) {
395  this->node_data.reserve(2);
396  }
397 
399  virtual ~SmiScenarioTree<T> () {
400  delete root_;
401  }
403 
404 private:
405  std::vector<T> node_data;
406  std::vector<T> scen_data;
407  std::vector<SmiTreeNode<T> *> leaf_;
409 };
410 
411 //#############################################################################
418 
419 #endif //SmiScenarioTree_H
std::vector< SmiTreeNode< T > * > * getChildren()
SmiTreeNode< T > * addNodesToTree(SmiTreeNode< T > *parent, int scenario, std::vector< T > &pathdata, int start)
Add new path from branching node to leaf.
std::vector< T >::iterator scenEnd(int s)
begin
SmiTreeNode< T > * find(std::vector< int > &label)
Get node identified by longest match to array of labels.
std::vector< SmiTreeNode< T > * > leaf_
SmiTreeNode< T > * getParent()
SmiTreeNode< T > * getChildP()
void setSibling(SmiTreeNode< T > *s)
void SmiScenarioTreeUnitTest()
A function that tests the methods in the SmiScenarioTree class.
void setScenario(int s)
std::vector< T > & getScenario(int scenario)
Get vector of node data for given scenario.
SmiTreeNode< T > * getSibling()
SmiTreeNode< T > * parent_
SmiTreeNode()
Default Constructor creates an empty node.
SmiTreeNode< T > * sibling_
std::vector< T > & wholeTree()
whole tree
SmiTreeNode< T > * root_
SmiTreeNode< T > * getRoot()
Get root node.
std::vector< T > node_data
Constant pos(const Constant &c)
for returning non-negative value of the constant.
SmiTreeNode< T > * addChild(T cd, int scenario)
void setLastChildLabel(int label)
int addPathtoLeaf(int brscenario, int stage, std::vector< T > &pathdata, unsigned int start=0)
Add new path from branching node to leaf.
SmiTreeNode< T > * getLeaf(int scn)
Get leaf node.
void setChild(SmiTreeNode< T > *c)
SmiTreeNode< T > * find(unsigned int scenario, int stage)
Get node identified by scenario/stage.
SmiTreeNode< T > * find(int *label, unsigned int sz)
Get node identified by longest match to array of labels.
int addPathtoLeaf(std::vector< int > &labels, std::vector< T > &pathdata)
Add new path using labels to find branching node.
std::vector< T >::iterator treeEnd()
end
SmiTreeNode< T > * getChildByLabel(int n)
void SmiTreeNodeUnitTest()
A function that tests the methods in the SmiTreeNode class.
std::map< int, SmiTreeNode< T > * > child_label_map
std::vector< T >::iterator scenBegin(int s)
scenario iterators TODO: native code for these iterators that does not depend on copying.
SmiTreeNode< T > * getParentP()
Scenario Tree.
SmiTreeNode< T > * getChild()
void setChildLabels(SmiTreeNode< T > *n, std::vector< int > labels)
Set child labels.
child_label_map child_labels_
SmiTreeNode< T > * child_
int getNumScenarios()
get number of scenarios
std::vector< T > scen_data
SmiTreeNode< T > * getSiblingP()
std::vector< T >::iterator treeBegin()
begin