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