Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

Node.cxx

Go to the documentation of this file.
00001 
00002 // C++
00003 #include <cmath>
00004 #include <iostream>
00005 
00006 #include "Node.h"
00007  
00008 //-------------------------------------------------------------------------------------------
00009 Lit::Node::Node(const Node *parent, const Event &event, const int mod) 
00010    :fNodeP(parent),
00011     fNodeL(0),
00012     fNodeR(0),
00013     fEvent(event),
00014     fVarDis(event.GetVar(mod)),
00015     fVarMin(fVarDis),
00016     fVarMax(fVarDis),
00017     fMod(mod)
00018 {   
00019 }
00020 
00021 //-------------------------------------------------------------------------------------------
00022 Lit::Node::~Node()
00023 {
00024    if(fNodeL) delete fNodeL;
00025    if(fNodeR) delete fNodeR;
00026 }
00027 
00028 //-------------------------------------------------------------------------------------------
00029 const Lit::Node* Lit::Node::Add(const Event &event, const unsigned int depth)
00030 {
00031    assert(fMod == depth % event.GetNVar());
00032    
00033    const VarType value = event.GetVar(fMod);
00034 
00035    fVarMin = std::min(fVarMin, value);
00036    fVarMax = std::max(fVarMax, value);
00037 
00038    Node *node = 0;
00039    if(value < fVarDis)
00040    {
00041       if(fNodeL)
00042       {
00043          return fNodeL -> Add(event, depth + 1);
00044       }
00045       else
00046       {
00047          fNodeL = new Node(this, event, (depth + 1) % event.GetNVar());
00048          node = fNodeL;
00049       }
00050    }
00051    else
00052    {
00053       if(fNodeR)
00054       {
00055          return fNodeR -> Add(event, depth + 1);
00056       }
00057       else
00058       {
00059          fNodeR = new Node(this, event, (depth + 1) % event.GetNVar());
00060          node = fNodeR;
00061       }      
00062    }
00063    
00064    return node;
00065 }
00066 
00067 //-------------------------------------------------------------------------------------------
00068 unsigned int Lit::Find(List &list, const Node *node, const Event &event, const unsigned int nfind)
00069 {
00070    if(!node)
00071    {
00072       return 0;
00073    }
00074 
00075    const VarType value = event.GetVar(node -> GetMod());
00076 
00077    if(node -> GetWeight() > 0.0)
00078    {      
00079       VarType max_dist = 0.0;
00080       if(!list.empty())
00081       {
00082          max_dist = list.back().second;
00083       
00084          if(list.size() == nfind)
00085          {
00086             if(value > node -> GetVarMax() && Lit::Distance(value, node -> GetVarMax()) > max_dist)
00087             {
00088                return 0;
00089             }  
00090             if(value < node -> GetVarMin() && Lit::Distance(value, node -> GetVarMin()) > max_dist)
00091             {
00092                return 0;
00093             }
00094          }
00095       }
00096       
00097       const VarType distance = Lit::Distance(event, node -> GetEvent());
00098       
00099       bool insert_this = false;
00100       bool remove_back = false;
00101       
00102       if(list.size() == nfind && !list.empty())
00103       {
00104          if(distance < max_dist)
00105          {
00106             insert_this = true;
00107             remove_back = true;
00108          }
00109       }
00110       else if(list.size() < nfind)
00111       {
00112          insert_this = true;
00113       }
00114       else
00115       {
00116          std::cerr << "Lit::Find() - logic error in recursive procedure" << std::endl;
00117          return 1;
00118       }
00119 
00120       if(insert_this)
00121       {
00122          List::iterator lit = list.begin();
00123          for(; lit != list.end(); ++lit)
00124          {
00125             if(distance < lit -> second)
00126             {
00127                break;
00128             }
00129             else
00130             {
00131                continue;
00132             }
00133          }
00134          
00135          list.insert(lit, Lit::Elem(node, distance));
00136       
00137          if(remove_back)
00138          {
00139             list.pop_back();
00140          }
00141       }
00142    }
00143 
00144    unsigned int count = 1;
00145    if(node -> GetNodeL() && node -> GetNodeR())
00146    {
00147       if(value < node -> GetVarDis())
00148       {
00149          count += Find(list, node -> GetNodeL(), event, nfind);
00150          count += Find(list, node -> GetNodeR(), event, nfind);
00151       }
00152       else
00153       {  
00154          count += Find(list, node -> GetNodeR(), event, nfind);
00155          count += Find(list, node -> GetNodeL(), event, nfind);
00156       }
00157    }
00158    else
00159    {
00160       if(node -> GetNodeL())
00161       {
00162          count += Find(list, node -> GetNodeL(), event, nfind);
00163       }
00164       if(node -> GetNodeR())
00165       {
00166          count += Find(list, node -> GetNodeR(), event, nfind);
00167       }
00168    }
00169 
00170    return count;
00171 }
00172 //-------------------------------------------------------------------------------------------
00173 unsigned int Lit::Find(List &list, const Node *node, const Event &event,
00174                        const double nfind, double ncurr)
00175 {
00176    if(!node || !(nfind > 0.0))
00177    {
00178       return 0;
00179    }
00180 
00181    const VarType value = event.GetVar(node -> GetMod());
00182 
00183    if(node -> GetWeight() > 0.0)
00184    {
00185       VarType max_dist = 0.0;
00186       if(!list.empty())
00187       {
00188          max_dist = list.back().second;
00189       
00190          if(!(ncurr < nfind))
00191          {
00192             if(value > node -> GetVarMax() && Lit::Distance(value, node -> GetVarMax()) > max_dist)
00193             {
00194                return 0;
00195             }
00196             if(value < node -> GetVarMin() && Lit::Distance(value, node -> GetVarMin()) > max_dist)
00197             {
00198                return 0;
00199             }
00200          }
00201       }
00202       
00203       const VarType distance = Lit::Distance(event, node -> GetEvent());
00204       
00205       bool insert_this = false;
00206       
00207       if(ncurr < nfind)
00208       {
00209          insert_this = true;
00210       }
00211       else if(!list.empty())
00212       {
00213          if(distance < max_dist)
00214          {
00215             insert_this = true;
00216          }
00217       }
00218       else
00219       {
00220          std::cerr << "Lit::Find() - logic error in recursive procedure" << std::endl;
00221          return 1;
00222       }
00223 
00224       if(insert_this)
00225       {
00226          ncurr = 0;
00227 
00228          List::iterator lit = list.begin();
00229          for(; lit != list.end(); ++lit)
00230          {
00231             if(distance < lit -> second)
00232             {
00233                break;
00234             }
00235           
00236             ncurr += lit -> first -> GetWeight();
00237          }
00238          
00239          lit = list.insert(lit, Lit::Elem(node, distance));     
00240 
00241          for(; lit != list.end(); ++lit)
00242          {
00243             ncurr += lit -> first -> GetWeight();
00244             if(!(ncurr < nfind))
00245             {
00246                ++lit;
00247                break;          
00248             }
00249          }
00250 
00251          if(lit != list.end())
00252          {
00253             list.erase(lit, list.end());
00254          }
00255       }
00256    }
00257 
00258    unsigned int count = 1;
00259    if(node -> GetNodeL() && node -> GetNodeR())
00260    {
00261       if(value < node -> GetVarDis())
00262       {
00263          count += Find(list, node -> GetNodeL(), event, nfind, ncurr);
00264          count += Find(list, node -> GetNodeR(), event, nfind, ncurr);
00265       }
00266       else
00267       {  
00268          count += Find(list, node -> GetNodeR(), event, nfind, ncurr);
00269          count += Find(list, node -> GetNodeL(), event, nfind, ncurr);
00270       }
00271    }
00272    else
00273    {
00274       if(node -> GetNodeL())
00275       {
00276          count += Find(list, node -> GetNodeL(), event, nfind, ncurr);
00277       }
00278       if(node -> GetNodeR())
00279       {
00280          count += Find(list, node -> GetNodeR(), event, nfind, ncurr);
00281       }
00282    }
00283 
00284    return count;
00285 }
00286 
00287 //-------------------------------------------------------------------------------------------
00288 void Lit::Node::Print() const
00289 {
00290    Print(std::cout);
00291 }
00292 
00293 //-------------------------------------------------------------------------------------------
00294 void Lit::Node::Print(std::ostream& os, const std::string &offset) const
00295 {
00296    os << offset << "-----------------------------------------------------------" << std::endl;
00297    os << offset << "Node: mod " << fMod 
00298       << " at " << fVarDis 
00299       << " with weight: " << GetWeight() << std::endl
00300       << offset << fEvent;
00301    
00302    if(fNodeL)
00303    {
00304       os << offset << "Has left node " << std::endl;
00305    }
00306    if(fNodeR)
00307    {
00308       os << offset << "Has right node" << std::endl;
00309    }
00310 
00311    if(fNodeL)
00312    {
00313       os << offset << "Print left node " << std::endl;
00314       fNodeL -> Print(os, offset + " ");
00315    }
00316    if(fNodeR)
00317    {
00318       os << offset << "Print right node" << std::endl;
00319       fNodeR -> Print(os, offset + " ");
00320    }
00321    
00322    if(!fNodeL && !fNodeR)
00323    {
00324       os << std::endl;
00325    }
00326 }
00327 
00328 
00329 //-------------------------------------------------------------------------------------------
00330 std::ostream& Lit::operator<<(std::ostream& os, const Lit::Node &node)
00331 { 
00332    node.Print(os);
00333    return os;
00334 }

Generated on Thu Nov 1 11:51:53 2007 for loon by  doxygen 1.3.9.1