00001
00002
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 }