00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <iostream>
00031 #include <algorithm>
00032 #include <float.h>
00033
00034 #ifdef _GLIBCXX_PARALLEL
00035 #include <omp.h>
00036 #endif
00037
00038 #include "TMVA/GeneticAlgorithm.h"
00039 #include "TMVA/Interval.h"
00040 #include "TMVA/IFitterTarget.h"
00041
00042 #include "TMVA/MsgLogger.h"
00043
00044 namespace TMVA {
00045 const Bool_t GeneticAlgorithm__DEBUG__ = kFALSE;
00046 }
00047
00048 ClassImp(TMVA::GeneticAlgorithm)
00049
00050
00051 TMVA::GeneticAlgorithm::GeneticAlgorithm( IFitterTarget& target, Int_t populationSize,
00052 const std::vector<Interval*>& ranges, UInt_t seed )
00053 : fConvCounter(-1),
00054 fFitterTarget( target ),
00055 fConvValue(0.),
00056 fLastResult(DBL_MAX),
00057 fSpread(0.1),
00058 fMirror(kTRUE),
00059 fFirstTime(kTRUE),
00060 fMakeCopies(kFALSE),
00061 fPopulationSize(populationSize),
00062 fRanges( ranges ),
00063 fPopulation(ranges, populationSize, seed),
00064 fBestFitness(DBL_MAX),
00065 fLogger( new MsgLogger("GeneticAlgorithm") )
00066 {
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 fPopulation.SetRandomSeed( seed );
00077 }
00078
00079 TMVA::GeneticAlgorithm::~GeneticAlgorithm()
00080 {
00081
00082 delete fLogger;
00083 }
00084
00085
00086
00087 void TMVA::GeneticAlgorithm::Init()
00088 {
00089
00090
00091
00092
00093 if ( fFirstTime ) fFirstTime = kFALSE;
00094 else {
00095 Evolution();
00096 }
00097 }
00098
00099
00100 Double_t TMVA::GeneticAlgorithm::NewFitness( Double_t , Double_t newValue )
00101 {
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114 return newValue;
00115 }
00116
00117
00118 Double_t TMVA::GeneticAlgorithm::CalculateFitness()
00119 {
00120
00121
00122
00123
00124
00125 fBestFitness = DBL_MAX;
00126 #ifdef _GLIBCXX_PARALLEL
00127
00128 const int nt = omp_get_num_threads();
00129 Double_t bests[nt];
00130 for ( int i =0; i < nt; ++i )
00131 bests[i] = fBestFitness;
00132
00133 #pragma omp parallel
00134 {
00135 int thread_number = omp_get_thread_num();
00136 #pragma omp for
00137 for ( int index = 0; index < fPopulation.GetPopulationSize(); ++index )
00138 {
00139 GeneticGenes* genes = fPopulation.GetGenes(index);
00140 Double_t fitness = NewFitness( genes->GetFitness(),
00141 fFitterTarget.EstimatorFunction(genes->GetFactors()) );
00142 genes->SetFitness( fitness );
00143
00144 if ( bests[thread_number] > fitness )
00145 bests[thread_number] = fitness;
00146 }
00147 }
00148
00149 fBestFitness = *std::min_element(bests, bests+nt);
00150
00151 #else
00152
00153 for ( int index = 0; index < fPopulation.GetPopulationSize(); ++index ) {
00154 GeneticGenes* genes = fPopulation.GetGenes(index);
00155 Double_t fitness = NewFitness( genes->GetFitness(),
00156 fFitterTarget.EstimatorFunction(genes->GetFactors()) );
00157 genes->SetFitness( fitness );
00158
00159 if ( fBestFitness > fitness )
00160 fBestFitness = fitness;
00161
00162 }
00163
00164 #endif
00165
00166 fPopulation.Sort();
00167
00168 return fBestFitness;
00169 }
00170
00171
00172 void TMVA::GeneticAlgorithm::Evolution()
00173 {
00174
00175
00176
00177
00178 if ( fMakeCopies )
00179 fPopulation.MakeCopies( 5 );
00180 fPopulation.MakeChildren();
00181
00182 fPopulation.Mutate( 10, 3, kTRUE, fSpread, fMirror );
00183 fPopulation.Mutate( 40, fPopulation.GetPopulationSize()*3/4 );
00184 }
00185
00186
00187 Double_t TMVA::GeneticAlgorithm::SpreadControl( Int_t ofSteps, Int_t successSteps, Double_t factor )
00188 {
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205 if ( fBestFitness < fLastResult || fSuccessList.size() <=0 ) {
00206 fLastResult = fBestFitness;
00207 fSuccessList.push_front( 1 );
00208 }
00209 else {
00210 fSuccessList.push_front( 0 );
00211 }
00212 Int_t n = 0;
00213 Int_t sum = 0;
00214 std::deque<Int_t>::iterator vec = fSuccessList.begin();
00215 for (; vec<fSuccessList.end() ; vec++) {
00216 sum += *vec;
00217 n++;
00218 }
00219
00220 if ( n >= ofSteps ) {
00221 fSuccessList.pop_back();
00222 if ( sum > successSteps ) {
00223 fSpread /= factor;
00224 if (GeneticAlgorithm__DEBUG__) Log() << kINFO << ">" << std::flush;
00225 }
00226 else if ( sum == successSteps ) {
00227 if (GeneticAlgorithm__DEBUG__) Log() << "=" << std::flush;
00228 }
00229 else {
00230 fSpread *= factor;
00231 if (GeneticAlgorithm__DEBUG__) Log() << "<" << std::flush;
00232 }
00233 }
00234
00235 return fSpread;
00236 }
00237
00238
00239 Bool_t TMVA::GeneticAlgorithm::HasConverged( Int_t steps, Double_t improvement )
00240 {
00241
00242
00243
00244
00245
00246
00247 if (fConvCounter < 0) {
00248 fConvValue = fBestFitness;
00249 }
00250 if (TMath::Abs(fBestFitness - fConvValue) <= improvement || steps<0) {
00251 fConvCounter ++;
00252 }
00253 else {
00254 fConvCounter = 0;
00255 fConvValue = fBestFitness;
00256 }
00257 if (GeneticAlgorithm__DEBUG__) Log() << "." << std::flush;
00258 if (fConvCounter < steps) return kFALSE;
00259 return kTRUE;
00260 }