src/ell/Basin.cc
Go to the documentation of this file.00001
00002 #include "ell/Basin.hh"
00003 #include "ell/util/PriorityQueue.hh"
00004 #include <biu/assertbiu.hh>
00005 #include <list>
00006
00007
00008 namespace ell
00009 {
00010
00011 Basin::QueueVal::QueueVal()
00012 : minNeigh(), minNeighE(0.0), minNeighGWE(UINT_MAX)
00013 {
00014 }
00015
00016 Basin::QueueVal::~QueueVal()
00017 {
00018 }
00019
00020
00021 Basin::Basin( const double maxE_,
00022 const double deltaE_,
00023 const size_t maxToStore_)
00024 : maxE(maxE_),
00025 deltaE(deltaE_),
00026 maxToStore(maxToStore_)
00027 {}
00028
00029 double
00030 Basin::flood( const ell::State* const localMin,
00031 StateCollector* scBasin,
00032 StateCollector* scSurface)
00033 {
00034 return Basin::basin( localMin, scBasin,
00035 maxE, deltaE, maxToStore, scSurface);
00036 }
00037
00038 double
00039 Basin::basin( const State* const localMin,
00040 StateCollector* scBasin,
00041 const double maxE_,
00042 const double deltaE,
00043 const size_t maxToStore,
00044 StateCollector* scSurface
00045 )
00046 {
00047 assertbiu( localMin != NULL, "No local Min given! (==NULL)");
00048 assertbiu( scBasin != NULL, "No StateCollector given! (scBasin==NULL)");
00049 assertbiu( localMin->getEnergy() < maxE_, "E(localMin) >= maxE");
00050
00051 using namespace ell::util;
00052
00053
00054 PriorityQueue<QueueVal> pq;
00055
00056 PriorityQueue<QueueVal>::iterator it = pq.insert(localMin);
00057 it->second.minNeigh.clear();
00058 it->second.minNeighE = it->first.E;
00059 it->second.minNeighGWE = 0;
00060
00061 double maxE = maxE_;
00062
00063 typedef std::list< PriorityQueue<QueueVal>::QueueKey > NeighList;
00064
00065 while (!pq.empty()) {
00066
00067 PriorityQueue<QueueVal>::const_iterator top = pq.top();
00068
00069 State* s = localMin->uncompress(top->first.s, NULL);
00070 CSequence minNeigh;
00071 double minNeighE = (double)INT_MAX;
00072
00073
00074
00075 State::NeighborListPtr neighbors = s->getNeighborList();
00076 State::NeighborList::Iterator it = neighbors->begin();
00077
00078 NeighList toStore;
00079
00080 while (neighbors->end() != it)
00081 {
00082
00083 double nextE = it->getEnergy();
00084 CSequence next = it->compress();
00085
00086 ++it;
00087
00088
00089 if ( (nextE < minNeighE) ||
00090 (nextE == minNeighE && next < minNeigh ) )
00091 {
00092 minNeigh = next;
00093 minNeighE = nextE;
00094 }
00095
00096 if ( nextE < maxE
00097 && ( nextE > top->first.E
00098 || (nextE == top->first.E && next > top->first.s)
00099
00100 ) )
00101 {
00102
00103 toStore.push_front(NeighList::value_type(nextE, next));
00104 }
00105
00106 }
00107
00108 if ( (minNeighE == top->second.minNeighE
00109 && minNeigh == top->second.minNeigh)
00110 || top->second.minNeigh.empty() )
00111 {
00112
00113 scBasin->add(*s);
00114
00115 PriorityQueue<QueueVal>::iterator toFill;
00116
00117 toStore.sort();
00118 for ( NeighList::const_iterator n = toStore.begin();
00119 n != toStore.end() && n->E < maxE;
00120 n++)
00121 {
00122 toFill = pq.find(*n);
00123 if (toFill == pq.end()) {
00124
00125 toFill = pq.insert(*n);
00126
00127 toFill->second.minNeigh = top->first.s;
00128 toFill->second.minNeighE = top->first.E;
00129 toFill->second.minNeighGWE = top->second.minNeighGWE;
00130
00131 if ( pq.size() >= maxToStore ) {
00132
00133 double curMaxE = pq.getMaxE();
00134
00135 do { maxE -= deltaE; } while (maxE > curMaxE);
00136
00137 pq.reduceMaxE(maxE);
00138 }
00139 } else
00140 if ( toFill->second.minNeighE > top->first.E ||
00141 ( toFill->second.minNeighE == top->first.E &&
00142 toFill->second.minNeigh > top->first.s) )
00143 {
00144
00145 toFill->second.minNeigh = top->first.s;
00146 toFill->second.minNeighE = top->first.E;
00147 toFill->second.minNeighGWE = top->second.minNeighGWE;
00148 }
00149 }
00150
00151 } else {
00152 if (scSurface != NULL) {
00153
00154 scSurface->add(*s);
00155 }
00156 }
00157
00158
00159 delete s;
00160
00161 pq.pop();
00162 }
00163
00164 return maxE;
00165 }
00166
00167
00168 }