00001
00002
00003 #ifndef SmiScenarioTree_H
00004 #define SmiScenarioTree_H
00005
00006 #if defined(_MSC_VER)
00007
00008 # pragma warning(disable:4786)
00009 #endif
00010
00016 #include <list>
00017 #include <vector>
00018 #include <map>
00019 #include <iostream>
00020 #include <assert.h>
00021
00022
00023 using namespace std;
00024
00033 template <class T>
00034 class SmiTreeNode {
00035
00036 public:
00037
00038 typedef map<int,SmiTreeNode<T>*> child_label_map;
00039
00040 bool hasParent() { return (parent_!=NULL); }
00041 bool hasChild() { return (child_!=NULL); }
00042 bool hasSibling(){ return (sibling_!=NULL);}
00043
00044 SmiTreeNode<T> *getParent() { return parent_; }
00045 SmiTreeNode<T> *getChild() { return child_; }
00046 SmiTreeNode<T> *getSibling(){ return sibling_;}
00047
00048 void setLastChildLabel(int label) { child_labels_.insert(make_pair(label,this->getChild()));}
00049
00050 SmiTreeNode<T> *getChildByLabel(int n){
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 typename child_label_map::iterator pos = child_labels_.find(n);
00063 if (pos!=child_labels_.end())
00064 return pos->second;
00065 else
00066 return NULL;
00067 }
00068
00069
00070 int depth() { return depth_; }
00071 int numChildren() { return nchild_; }
00072 int scenario() {return scen_; }
00073 void setScenario(int s) {scen_=s; }
00074
00075
00076 SmiTreeNode<T> * addChild(T cd, int scenario)
00077 {
00078 SmiTreeNode<T> *c = new SmiTreeNode(cd);
00079
00080 c->parent_ = this;
00081 c->depth_ = depth_ + 1;
00082 c->sibling_ = child_;
00083 c->scen_ = scenario;
00084 nchild_++;
00085 child_ = c;
00086 return c;
00087 }
00088
00089 vector<SmiTreeNode<T> *> *getChildren()
00090 {
00091 SmiTreeNode<T> *pnode = this;
00092 int i = this->numChildren();
00093 if (i==0){
00094 return NULL;
00095 }
00096 vector<SmiTreeNode<T> *> *vec = new vector<SmiTreeNode<T> *>(i);
00097 (*vec)[--i] = pnode = pnode->getChild();
00098 while (i>0)
00099 (*vec)[--i] = pnode = pnode->getSibling();
00100 return vec;
00101 }
00102
00103 T getDataPtr() { return ptr_; }
00104
00105
00108
00109 SmiTreeNode<T>(){
00110 parent_=NULL;
00111 child_=NULL;
00112 sibling_= NULL;
00113 nchild_ = 0;
00114 depth_ = 0;
00115 scen_ = -1;
00116 }
00117
00119 SmiTreeNode<T>(T p){
00120 parent_=NULL;
00121 child_=NULL;
00122 sibling_= NULL;
00123 nchild_ = 0;
00124 depth_ = 0;
00125 ptr_ = p;
00126 scen_ = -1;
00127 }
00128
00130
00131 ~SmiTreeNode()
00132 {
00133
00134
00135 delete ptr_ ;
00136 }
00137
00139
00140 protected:
00141
00142 void setChild (SmiTreeNode<T> *c) {child_ = c;}
00143 void setSibling(SmiTreeNode<T> *s) {sibling_ = s;}
00144 SmiTreeNode<T> *getParentP() { return parent_; }
00145 SmiTreeNode<T> *getChildP() { return child_; }
00146 SmiTreeNode<T> *getSiblingP(){ return sibling_;}
00147
00148
00149 private:
00150 SmiTreeNode<T> *parent_;
00151 SmiTreeNode<T> *child_;
00152 SmiTreeNode<T> *sibling_;
00153 int scen_;
00154 int nchild_;
00155 int depth_;
00156 T ptr_;
00157 child_label_map child_labels_;
00158
00159 };
00160
00161
00167 void
00168 SmiTreeNodeUnitTest();
00169
00170
00171 template<class T>
00172 class SmiScenarioTree {
00173
00174 public:
00175
00176
00179
00180
00182 typename vector<T>::iterator treeBegin(){ return node_data.begin(); }
00184 typename vector<T>::iterator treeEnd(){ return node_data.end();}
00186 vector<T> &wholeTree(){ return node_data;}
00187
00191 typename vector<T>::iterator scenBegin(int s){
00192 getScenario(s);
00193 return scen_data.begin();
00194 }
00195
00196 typename vector<T>::iterator scenEnd(int s){
00197 getScenario(s);
00198 return scen_data.begin()+leaf_[s]->depth()+1;
00199 }
00200
00201
00202
00203
00204
00207
00209 SmiTreeNode<T> *getRoot() { return root_; }
00210
00212 SmiTreeNode<T> *getLeaf(int scn) { return leaf_[scn];}
00213
00215 SmiTreeNode<T> *find(unsigned int scenario, int stage)
00216 {
00217 assert (scenario < leaf_.size());
00218 SmiTreeNode<T> * n = leaf_[scenario];
00219 assert (stage < n->depth() + 1);
00220 while (stage < n->depth())
00221 n = n->getParent();
00222 return n;
00223 }
00224
00226 int getNumScenarios()
00227 {
00228 return leaf_.size();
00229 }
00230
00231
00233 SmiTreeNode<T> *find(vector<int> &label)
00234 {
00235 assert(label.size()>0);
00236 SmiTreeNode<T> *n = root_,*next;
00237 unsigned int i=0;
00238 while ((i<label.size()) && (next=n->getChildByLabel(label[i])))
00239 {
00240 ++i;
00241 n=next;
00242 }
00243 return n;
00244 }
00245
00246
00248 vector<T> &getScenario(int scenario)
00249 {
00250 assert (scenario < (int) leaf_.size());
00251 SmiTreeNode<T> * n = leaf_[scenario];
00252
00253
00254
00255 int ns=n->depth()+1-scen_data.size();
00256 for (int j=0; j<ns;j++)
00257 scen_data.push_back(n->getDataPtr());
00258
00259 int i=n->depth()+1;
00260 while(i>0)
00261 {
00262 scen_data[--i] = n->getDataPtr();
00263 n = n->getParent();
00264 }
00265 return scen_data;
00266 }
00267
00268
00270
00271
00281 int addPathtoLeaf(int brscenario, int stage, vector<T> &pathdata, unsigned int start=0)
00282 {
00283 SmiTreeNode<T> *parent = NULL;
00284 int scenario=leaf_.size();
00285 if (scenario)
00286 parent = find(brscenario,stage);
00287
00288
00289 for (unsigned int i=start; i<pathdata.size(); ++i)
00290 {
00291 if (parent)
00292 {
00293 parent = parent->addChild(pathdata[i],scenario);
00294 }
00295 else
00296 {
00297 parent = root_ = new SmiTreeNode<T>(pathdata[0]);
00298 root_->setScenario(scenario);
00299 }
00300
00301 node_data.push_back(pathdata[i]);
00302 }
00303 if (pathdata.size())
00304 {
00305 leaf_.push_back(parent);
00306 }
00307 return leaf_.size()-1;
00308
00309 }
00310
00312 void setChildLabels(SmiTreeNode<T> *n, vector<int> labels)
00313 {
00314 int t = n->depth();
00315 while(n->hasChild())
00316 {
00317 n->setLastChildLabel(labels[++t]);
00318 n = n->getChild();
00319 }
00320 }
00321
00322
00329 int addPathtoLeaf(vector<int>labels, vector<T> &pathdata)
00330 {
00331 SmiTreeNode<T> *parent = NULL;
00332 int scenario=leaf_.size();
00333 if (scenario)
00334 parent = find(labels);
00335
00336 unsigned int i=0;
00337 if (parent) i=parent->depth()+1;
00338
00339 for (; i<pathdata.size(); ++i)
00340 {
00341 if (parent)
00342 {
00343 parent = parent->addChild(pathdata[i],scenario);
00344
00345 }
00346 else
00347 {
00348 parent = root_ = new SmiTreeNode<T>(pathdata[0]);
00349 root_->setScenario(scenario);
00350 }
00351
00352 node_data.push_back(pathdata[i]);
00353 }
00354 if (pathdata.size())
00355 {
00356 leaf_.push_back(parent);
00357 }
00358 return leaf_.size()-1;
00359
00360 }
00362
00365
00366 SmiScenarioTree<T>(): leaf_(0),root_(NULL) {};
00367
00369
00370 virtual ~SmiScenarioTree<T>() {};
00372
00373 private:
00374 vector<T> node_data;
00375 vector<T> scen_data;
00376 vector<SmiTreeNode<T> *> leaf_;
00377 SmiTreeNode<T> *root_;
00378 };
00379
00380
00386 void
00387 SmiScenarioTreeUnitTest();
00388
00389 #endif //SmiScenarioTree_H