Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifndef __RD_MAXMINPICKER_H__
00011 #define __RD_MAXMINPICKER_H__
00012
00013 #include <RDGeneral/types.h>
00014 #include <RDGeneral/utils.h>
00015 #include <RDGeneral/Invariant.h>
00016 #include <RDGeneral/RDLog.h>
00017 #include <RDBoost/Exceptions.h>
00018 #include <cstdlib>
00019 #include "DistPicker.h"
00020 #include <boost/random.hpp>
00021
00022 namespace RDPickers {
00023
00024 namespace {
00025 class distmatFunctor{
00026 public:
00027 distmatFunctor(const double *distMat) : dp_distMat(distMat) {};
00028 double operator()(unsigned int i,unsigned int j) {
00029 return getDistFromLTM(this->dp_distMat,i,j);
00030 }
00031 private:
00032 const double *dp_distMat;
00033 };
00034 }
00035
00036
00037
00038
00039
00040
00041 class MaxMinPicker : public DistPicker {
00042 public:
00043
00044
00045
00046 MaxMinPicker() {};
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061 template <typename T>
00062 RDKit::INT_VECT lazyPick(T &func,
00063 unsigned int poolSize, unsigned int pickSize,
00064 RDKit::INT_VECT firstPicks=RDKit::INT_VECT(),
00065 int seed=-1) const;
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097 RDKit::INT_VECT pick(const double *distMat,
00098 unsigned int poolSize, unsigned int pickSize,
00099 RDKit::INT_VECT firstPicks,
00100 int seed=-1) const {
00101 CHECK_INVARIANT(distMat, "Invalid Distance Matrix");
00102 if(poolSize<pickSize)
00103 throw ValueErrorException("pickSize cannot be larger than the poolSize");
00104 distmatFunctor functor(distMat);
00105 return this->lazyPick(functor,poolSize,pickSize,firstPicks,seed);
00106 }
00107
00108
00109 RDKit::INT_VECT pick(const double *distMat,
00110 unsigned int poolSize, unsigned int pickSize) const {
00111 RDKit::INT_VECT iv;
00112 return pick(distMat,poolSize,pickSize,iv);
00113 }
00114
00115
00116
00117 };
00118
00119 template <typename T>
00120 RDKit::INT_VECT MaxMinPicker::lazyPick(T &func,
00121 unsigned int poolSize, unsigned int pickSize,
00122 RDKit::INT_VECT firstPicks,
00123 int seed) const {
00124 if(poolSize<pickSize)
00125 throw ValueErrorException("pickSize cannot be larger than the poolSize");
00126
00127 RDKit::INT_LIST pool;
00128
00129 RDKit::INT_VECT picks;
00130 picks.reserve(pickSize);
00131 unsigned int pick=0;
00132
00133
00134 for (unsigned int i = 0; i < poolSize; i++) {
00135 pool.push_back(i);
00136 }
00137
00138
00139
00140 typedef boost::mt19937 rng_type;
00141 typedef boost::uniform_int<> distrib_type;
00142 typedef boost::variate_generator<rng_type &,distrib_type> source_type;
00143 rng_type generator(42u);
00144 distrib_type dist(0,poolSize);
00145 source_type randomSource(generator,dist);
00146 if(seed>0) generator.seed(static_cast<rng_type::result_type>(seed));
00147
00148
00149 if(!firstPicks.size()){
00150 pick = randomSource();
00151
00152 picks.push_back(pick);
00153
00154 pool.remove(pick);
00155 } else{
00156 for(RDKit::INT_VECT::const_iterator pIdx=firstPicks.begin();
00157 pIdx!=firstPicks.end();++pIdx){
00158 pick = static_cast<unsigned int>(*pIdx);
00159 if(pick>=poolSize)
00160 throw ValueErrorException("pick index was larger than the poolSize");
00161 picks.push_back(pick);
00162 pool.remove(pick);
00163 }
00164 }
00165
00166 while (picks.size() < pickSize) {
00167 double maxOFmin = -1.0;
00168 RDKit::INT_LIST_I plri=pool.end();
00169 for(RDKit::INT_LIST_I pli=pool.begin();
00170 pli!=pool.end(); ++pli){
00171 unsigned int poolIdx = (*pli);
00172 double minTOi = RDKit::MAX_DOUBLE;
00173 for (RDKit::INT_VECT_CI pi = picks.begin();
00174 pi != picks.end(); ++pi) {
00175 unsigned int pickIdx = (*pi);
00176 CHECK_INVARIANT(poolIdx!=pickIdx,"");
00177 double dist = func(poolIdx,pickIdx);
00178 if (dist <= minTOi) {
00179 minTOi = dist;
00180 }
00181 }
00182 if (minTOi > maxOFmin || (RDKit::feq(minTOi,maxOFmin) && poolIdx<pick) ) {
00183 maxOFmin = minTOi;
00184 pick = poolIdx;
00185 plri = pli;
00186 }
00187 }
00188
00189
00190 picks.push_back(pick);
00191 CHECK_INVARIANT(plri!=pool.end(),"");
00192 pool.erase(plri);
00193 }
00194 return picks;
00195 }
00196
00197
00198 };
00199
00200 #endif