00001
00002 #include "ell/Basin.hh"
00003 #include <biu/assertbiu.hh>
00004
00005
00006
00007
00008 namespace ell
00009 {
00010
00011 Basin::~Basin()
00012 {}
00013
00014
00015 }
00016
00017
00018
00019
00020 #include "ell/util/PriorityQueue.hh"
00021 #include <list>
00022
00023 namespace ell {
00024
00025 Basin_FME::QueueVal::QueueVal()
00026 : minNeigh(), minNeighE(0.0), minNeighGWE(UINT_MAX)
00027 {
00028 }
00029
00030 Basin_FME::QueueVal::~QueueVal()
00031 {
00032 }
00033
00034
00035 Basin_FME::Basin_FME( const double maxE_,
00036 const double deltaE_,
00037 const size_t maxToStore_)
00038 : maxE(maxE_),
00039 deltaE(deltaE_),
00040 maxToStore(maxToStore_)
00041 {}
00042
00043 Basin_FME::~Basin_FME()
00044 {}
00045
00046 double
00047 Basin_FME::enumerate( const State* const localMin,
00048 StateCollector* scBasin,
00049 StatePairCollector* scSurface)
00050 {
00051 return Basin_FME::flood( localMin, scBasin,
00052 maxE, deltaE, maxToStore, scSurface);
00053 }
00054
00055 double
00056 Basin_FME::flood(
00057 const State* const localMin,
00058 StateCollector* scBasin,
00059 const double maxE_,
00060 const double deltaE,
00061 const size_t maxToStore,
00062 StatePairCollector* scSurface
00063 )
00064 {
00065 assertbiu( localMin != NULL, "No local Min given! (==NULL)");
00066 assertbiu( scBasin != NULL, "No StateCollector given! (scBasin==NULL)");
00067 assertbiu( localMin->getEnergy() <= maxE_, "E(localMin) <= maxE");
00068
00069 using namespace ell::util;
00070
00071
00072 PriorityQueue<QueueVal> pq;
00073
00074 PriorityQueue<QueueVal>::InsertResult it = pq.insert(localMin);
00075 it.first->second.minNeigh.clear();
00076 it.first->second.minNeighE = it.first->first.E;
00077 it.first->second.minNeighGWE = 0;
00078
00079 double maxE = maxE_;
00080
00081 typedef std::list< PriorityQueue<QueueVal>::QueueKey > NeighList;
00082
00083 State* topState = localMin->clone();
00084
00085 while (!pq.empty()) {
00086
00087 PriorityQueue<QueueVal>::const_iterator top = pq.top();
00088
00089 topState->uncompress(top->first.s);
00090 CSequence minNeigh;
00091 double minNeighE = (double)INT_MAX;
00092
00093
00094
00095 State::NeighborListPtr neighbors = topState->getNeighborList();
00096 State::NeighborList::Iterator it = neighbors->begin();
00097
00098 NeighList toStore;
00099
00100 CSequence next;
00101
00102 while (neighbors->end() != it)
00103 {
00104
00105 double nextE = it->getEnergy();
00106 next = it->compress( next );
00107
00108 ++it;
00109
00110
00111 if ( (nextE < minNeighE) ||
00112 (nextE == minNeighE && next < minNeigh ) )
00113 {
00114 minNeigh = next;
00115 minNeighE = nextE;
00116 }
00117
00118 if ( nextE <= maxE
00119 && ( nextE > top->first.E
00120 || (nextE == top->first.E && next > top->first.s)
00121
00122 ) )
00123 {
00124
00125 toStore.push_front(NeighList::value_type(nextE, next));
00126 }
00127
00128 }
00129
00130 if ( (minNeighE == top->second.minNeighE
00131 && minNeigh == top->second.minNeigh)
00132 || top->second.minNeigh.empty() )
00133 {
00134
00135 scBasin->add(*topState);
00136
00137 PriorityQueue<QueueVal>::iterator toFill;
00138
00139 toStore.sort();
00140 for ( NeighList::const_iterator n = toStore.begin();
00141 n != toStore.end() && n->E <= maxE;
00142 n++)
00143 {
00144 toFill = pq.find(*n);
00145 if (toFill == pq.end()) {
00146
00147 toFill = pq.insert(*n).first;
00148
00149 toFill->second.minNeigh = top->first.s;
00150 toFill->second.minNeighE = top->first.E;
00151 toFill->second.minNeighGWE = top->second.minNeighGWE;
00152
00153 if ( pq.size() >= maxToStore ) {
00154
00155 double curMaxE = pq.getMaxE();
00156
00157 do { maxE -= deltaE; } while (maxE > curMaxE);
00158
00159 pq.reduceMaxE(maxE+0.00000001);
00160 }
00161 } else
00162 if ( toFill->second.minNeighE > top->first.E ||
00163 ( toFill->second.minNeighE == top->first.E &&
00164 toFill->second.minNeigh > top->first.s) )
00165 {
00166
00167 toFill->second.minNeigh = top->first.s;
00168 toFill->second.minNeighE = top->first.E;
00169 toFill->second.minNeighGWE = top->second.minNeighGWE;
00170 }
00171 }
00172
00173
00174
00175
00176
00177
00178 }
00179
00180
00181 pq.pop();
00182 }
00183
00184 delete topState;
00185
00186 return maxE;
00187 }
00188
00189 }
00190
00191
00192
00193
00194
00195 #include "ell/util/PriorityQueue.hh"
00196 #include <list>
00197 #include <set>
00198
00199 namespace ell {
00200
00201 Basin_F::QueueVal::QueueVal()
00202 : minNeigh(), minNeighE(0.0), minNeighGWE(UINT_MAX)
00203 {
00204 }
00205
00206 Basin_F::QueueVal::~QueueVal()
00207 {
00208 }
00209
00210
00211 Basin_F::Basin_F( const double maxE_,
00212 const double deltaE_,
00213 const size_t maxToStore_ )
00214 : maxE(maxE_),
00215 deltaE(deltaE_),
00216 maxToStore(maxToStore_)
00217 {}
00218
00219 Basin_F::~Basin_F()
00220 {}
00221
00222 double
00223 Basin_F::enumerate( const State* const localMin,
00224 StateCollector* scBasin,
00225 StatePairCollector* scSurface)
00226 {
00227 return Basin_F::flood( localMin, scBasin,
00228 maxE, deltaE, maxToStore, scSurface);
00229 }
00230
00231 double
00232 Basin_F::flood(
00233 const State* const localMin,
00234 StateCollector* scBasin,
00235 const double maxE_,
00236 const double deltaE,
00237 const size_t maxToStore,
00238 StatePairCollector* scSurface
00239 )
00240 {
00241 assertbiu( localMin != NULL, "No local Min given! (==NULL)");
00242 assertbiu( scBasin != NULL, "No StateCollector given! (scBasin==NULL)");
00243 assertbiu( localMin->getEnergy() <= maxE_, "E(localMin) <= maxE");
00244
00245 using namespace ell::util;
00246
00247
00248 PriorityQueue<QueueVal> pq;
00249
00250 typedef std::set<CSequence> BasinHash;
00251 BasinHash handled;
00252
00253 PriorityQueue<QueueVal>::InsertResult it = pq.insert(localMin);
00254 it.first->second.minNeigh.clear();
00255 it.first->second.minNeighE = it.first->first.E;
00256 it.first->second.minNeighGWE = 0;
00257
00258 double maxE = maxE_;
00259
00260 typedef std::list< PriorityQueue<QueueVal>::QueueKey > NeighList;
00261
00262
00263 State* topState = localMin->clone();
00264 State* curNeigh = localMin->clone();
00265
00266 while (!pq.empty()) {
00267
00268 PriorityQueue<QueueVal>::const_iterator top = pq.top();
00269
00270 topState->uncompress(top->first.s);
00271 CSequence minNeigh;
00272 double minNeighE = (double)INT_MAX;
00273
00274
00275
00276 State::NeighborListPtr neighbors = topState->getNeighborList();
00277 State::NeighborList::Iterator it = neighbors->begin();
00278
00279 NeighList toStore;
00280
00281 NeighList toCheck;
00282
00283 CSequence next;
00284
00285 while (neighbors->end() != it)
00286 {
00287
00288 double nextE = it->getEnergy();
00289 next = it->compress( next );
00290
00291 ++it;
00292
00293
00294 if ( (nextE < minNeighE) ||
00295 (nextE == minNeighE && next < minNeigh ) )
00296 {
00297 minNeigh = next;
00298 minNeighE = nextE;
00299 }
00300
00301 if ( nextE <= maxE )
00302 {
00303
00304 if ( nextE > top->first.E
00305 || (nextE == top->first.E && next > top->first.s) )
00306 {
00307
00308 toStore.push_front(NeighList::value_type(nextE, next));
00309
00310 } else if (scSurface != NULL) {
00311
00312 toCheck.push_back(NeighList::value_type(nextE, next));
00313 }
00314 }
00315
00316 }
00317
00318 if ( (minNeighE == top->second.minNeighE
00319 && minNeigh == top->second.minNeigh)
00320 || top->second.minNeigh.empty() )
00321 {
00322
00323 scBasin->add(*topState);
00324
00325 handled.insert(top->first.s);
00326
00327
00328 PriorityQueue<QueueVal>::iterator toFill;
00329
00330 toStore.sort();
00331 for ( NeighList::const_iterator n = toStore.begin();
00332 n != toStore.end() && n->E <= maxE;
00333 n++)
00334 {
00335 toFill = pq.find(*n);
00336 if (toFill == pq.end()) {
00337
00338 toFill = pq.insert(*n).first;
00339
00340 toFill->second.minNeigh = top->first.s;
00341 toFill->second.minNeighE = top->first.E;
00342 toFill->second.minNeighGWE = top->second.minNeighGWE;
00343
00344 if ( pq.size() >= maxToStore ) {
00345
00346 double curMaxE = pq.getMaxE();
00347
00348 do { maxE -= deltaE; } while (maxE > curMaxE);
00349
00350 pq.reduceMaxE(maxE);
00351 }
00352 } else
00353 if ( toFill->second.minNeighE > top->first.E ||
00354 ( toFill->second.minNeighE == top->first.E &&
00355 toFill->second.minNeigh > top->first.s) )
00356 {
00357
00358 toFill->second.minNeigh = top->first.s;
00359 toFill->second.minNeighE = top->first.E;
00360 toFill->second.minNeighGWE = top->second.minNeighGWE;
00361 }
00362 }
00363
00364 if (scSurface != NULL) {
00365
00366
00367 for ( NeighList::const_iterator n = toCheck.begin();
00368 n != toCheck.end(); n++)
00369 {
00370
00371 if ( handled.find(n->s) == handled.end() ) {
00372
00373 curNeigh->uncompress(n->s);
00374
00375 scSurface->add( topState, curNeigh );
00376 }
00377 }
00378 }
00379
00380 } else {
00381
00382
00383 if (scSurface != NULL) {
00384
00385
00386 for ( NeighList::const_iterator n = toCheck.begin();
00387 n != toCheck.end(); n++)
00388 {
00389
00390 if ( handled.find(n->s) != handled.end() ) {
00391
00392 curNeigh->uncompress(n->s);
00393
00394 scSurface->add( curNeigh, topState );
00395 }
00396 }
00397 }
00398 }
00399
00400
00401 pq.pop();
00402 }
00403
00404 delete topState;
00405 delete curNeigh;
00406
00407 return maxE;
00408 }
00409
00410 }
00411
00412
00413
00414