ROOT logo
// @(#)root/tmva $Id: GeneticFitter.cxx 29195 2009-06-24 10:39:49Z brun $ 
// Author: Peter Speckmayer

/**********************************************************************************
 * Project: TMVA - a Root-integrated toolkit for multivariate data analysis       *
 * Package: TMVA                                                                  *
 * Class  : GeneticFitter                                                         *
 * Web    : http://tmva.sourceforge.net                                           *
 *                                                                                *
 * Description:                                                                   *
 *      Implementation                                                            *
 *                                                                                *
 * Authors (alphabetical):                                                        *
 *      Peter Speckmayer <speckmay@mail.cern.ch> - CERN, Switzerland              *
 *                                                                                *
 * Copyright (c) 2005:                                                            *
 *      CERN, Switzerland                                                         * 
 *      MPI-K Heidelberg, Germany                                                 * 
 *                                                                                *
 * Redistribution and use in source and binary forms, with or without             *
 * modification, are permitted according to the terms listed in LICENSE           *
 * (http://tmva.sourceforge.net/LICENSE)                                          *
 **********************************************************************************/

//_______________________________________________________________________
//                                                                      
// Fitter using a Genetic Algorithm
//_______________________________________________________________________

#include <iostream>

#include "TMVA/GeneticFitter.h"
#include "TMVA/GeneticAlgorithm.h"
#include "TMVA/Interval.h"
#include "TMVA/Timer.h"

ClassImp(TMVA::GeneticFitter)

//_______________________________________________________________________
TMVA::GeneticFitter::GeneticFitter( IFitterTarget& target, 
                                    const TString& name, 
                                    const std::vector<TMVA::Interval*>& ranges, 
                                    const TString& theOption ) 
   : FitterBase( target, name, ranges, theOption )
{
   // constructor

   // default parameters settings for Genetic Algorithm
   DeclareOptions();
   ParseOptions();
}            

//_______________________________________________________________________
void TMVA::GeneticFitter::DeclareOptions() 
{
   // declare GA options

   DeclareOptionRef( fPopSize=300,    "PopSize",   "Population size for GA" );  
   DeclareOptionRef( fNsteps=40,      "Steps",     "Number of steps for convergence" );  
   DeclareOptionRef( fCycles=3,       "Cycles",    "Independent cycles of GA fitting" );  
   DeclareOptionRef( fSC_steps=10,    "SC_steps",  "Spread control, steps" );  
   DeclareOptionRef( fSC_rate=5,      "SC_rate",   "Spread control, rate: factor is changed depending on the rate" );  
   DeclareOptionRef( fSC_factor=0.95, "SC_factor", "Spread control, factor" );  
   DeclareOptionRef( fConvCrit=0.001, "ConvCrit",   "Convergence criteria" );  

   DeclareOptionRef( fSaveBestFromGeneration=1, "SaveBestGen", 
                     "Saves the best n results from each generation. They are included in the last cycle" );  
   DeclareOptionRef( fSaveBestFromCycle=10,     "SaveBestCycle", 
                     "Saves the best n results from each cycle. They are included in the last cycle. The value should be set to at least 1.0" );  
   
   DeclareOptionRef( fTrim=kFALSE, "Trim", 
                     "Trim the population to PopSize after assessing the fitness of each individual" );  
   DeclareOptionRef( fSeed=100, "Seed", "Set seed of random generator (0 gives random seeds)" );  
}

//_______________________________________________________________________
void TMVA::GeneticFitter::SetParameters(  Int_t cycles,
                                          Int_t nsteps,
                                          Int_t popSize,
                                          Int_t SC_steps,
                                          Int_t SC_rate,
                                          Double_t SC_factor,
                                          Double_t convCrit)
{
   // set GA configuration parameters
   fNsteps    = nsteps;
   fCycles    = cycles;
   fPopSize   = popSize;
   fSC_steps  = SC_steps;
   fSC_rate   = SC_rate;
   fSC_factor = SC_factor;
   fConvCrit  = convCrit;
}

//_______________________________________________________________________
Double_t TMVA::GeneticFitter::Run( std::vector<Double_t>& pars )
{
   // Execute fitting
   Log() << kINFO << "<GeneticFitter> Optimisation, please be patient "
         << "... (inaccurate progress timing for GA)" << Endl;

   GetFitterTarget().ProgressNotifier( "GA", "init" );

   GeneticAlgorithm gstore( GetFitterTarget(),  fPopSize, fRanges);
   //   gstore.SetMakeCopies(kTRUE);  // commented out, because it reduces speed

   // timing of GA
   Timer timer( 100*(fCycles), GetName() ); 
   timer.DrawProgressBar( 0 );

   Double_t progress = 0.;

   for (Int_t cycle = 0; cycle < fCycles; cycle++) {
      GetFitterTarget().ProgressNotifier( "GA", "cycle" );
      // ---- perform series of fits to achieve best convergence
         
      // "m_ga_spread" times the number of variables
      GeneticAlgorithm ga( GetFitterTarget(), fPopSize, fRanges, fSeed ); 
      //      ga.SetMakeCopies(kTRUE);  // commented out, because it reduces speed

      if ( pars.size() == fRanges.size() ){
         ga.GetGeneticPopulation().GiveHint( pars, 0.0 );
      }
      if (cycle==fCycles-1) {
         GetFitterTarget().ProgressNotifier( "GA", "last" );
         ga.GetGeneticPopulation().AddPopulation( gstore.GetGeneticPopulation() );
      }

      GetFitterTarget().ProgressNotifier( "GA", "iteration" );

      ga.CalculateFitness();
      ga.GetGeneticPopulation().TrimPopulation();

      Double_t n=0.;
      do {
         GetFitterTarget().ProgressNotifier( "GA", "iteration" );
         ga.Init();
         ga.CalculateFitness();
         if ( fTrim ) ga.GetGeneticPopulation().TrimPopulation();
         ga.SpreadControl( fSC_steps, fSC_rate, fSC_factor );

         // monitor progrss
         if (ga.fConvCounter > n) n = Double_t(ga.fConvCounter);
         progress = 100*((Double_t)cycle) + 100*(n/Double_t(fNsteps)); 

         timer.DrawProgressBar( (Int_t)progress );
          
         // Copy the best genes of the generation
         ga.GetGeneticPopulation().Sort();
         for ( Int_t i = 0; i<fSaveBestFromGeneration && i<fPopSize; i++ ) {
            gstore.GetGeneticPopulation().GiveHint( ga.GetGeneticPopulation().GetGenes(i)->GetFactors(), 
                                                    ga.GetGeneticPopulation().GetGenes(i)->GetFitness() );
         }
      } while (!ga.HasConverged( fNsteps, fConvCrit ));                

      timer.DrawProgressBar( 100*(cycle+1) );
      
      ga.GetGeneticPopulation().Sort();
      for ( Int_t i = 0; i<fSaveBestFromGeneration && i<fPopSize; i++ ) {
         gstore.GetGeneticPopulation().GiveHint( ga.GetGeneticPopulation().GetGenes(i)->GetFactors(), 
                                                 ga.GetGeneticPopulation().GetGenes(i)->GetFitness() );
      }
   }

   // get elapsed time   
   Log() << kINFO << "Elapsed time: " << timer.GetElapsedTime() 
         << "                            " << Endl;  

   Double_t fitness = gstore.CalculateFitness();
   gstore.GetGeneticPopulation().Sort();
   pars.swap( gstore.GetGeneticPopulation().GetGenes(0)->GetFactors() );

   GetFitterTarget().ProgressNotifier( "GA", "stop" );
   return fitness;
}
 GeneticFitter.cxx:1
 GeneticFitter.cxx:2
 GeneticFitter.cxx:3
 GeneticFitter.cxx:4
 GeneticFitter.cxx:5
 GeneticFitter.cxx:6
 GeneticFitter.cxx:7
 GeneticFitter.cxx:8
 GeneticFitter.cxx:9
 GeneticFitter.cxx:10
 GeneticFitter.cxx:11
 GeneticFitter.cxx:12
 GeneticFitter.cxx:13
 GeneticFitter.cxx:14
 GeneticFitter.cxx:15
 GeneticFitter.cxx:16
 GeneticFitter.cxx:17
 GeneticFitter.cxx:18
 GeneticFitter.cxx:19
 GeneticFitter.cxx:20
 GeneticFitter.cxx:21
 GeneticFitter.cxx:22
 GeneticFitter.cxx:23
 GeneticFitter.cxx:24
 GeneticFitter.cxx:25
 GeneticFitter.cxx:26
 GeneticFitter.cxx:27
 GeneticFitter.cxx:28
 GeneticFitter.cxx:29
 GeneticFitter.cxx:30
 GeneticFitter.cxx:31
 GeneticFitter.cxx:32
 GeneticFitter.cxx:33
 GeneticFitter.cxx:34
 GeneticFitter.cxx:35
 GeneticFitter.cxx:36
 GeneticFitter.cxx:37
 GeneticFitter.cxx:38
 GeneticFitter.cxx:39
 GeneticFitter.cxx:40
 GeneticFitter.cxx:41
 GeneticFitter.cxx:42
 GeneticFitter.cxx:43
 GeneticFitter.cxx:44
 GeneticFitter.cxx:45
 GeneticFitter.cxx:46
 GeneticFitter.cxx:47
 GeneticFitter.cxx:48
 GeneticFitter.cxx:49
 GeneticFitter.cxx:50
 GeneticFitter.cxx:51
 GeneticFitter.cxx:52
 GeneticFitter.cxx:53
 GeneticFitter.cxx:54
 GeneticFitter.cxx:55
 GeneticFitter.cxx:56
 GeneticFitter.cxx:57
 GeneticFitter.cxx:58
 GeneticFitter.cxx:59
 GeneticFitter.cxx:60
 GeneticFitter.cxx:61
 GeneticFitter.cxx:62
 GeneticFitter.cxx:63
 GeneticFitter.cxx:64
 GeneticFitter.cxx:65
 GeneticFitter.cxx:66
 GeneticFitter.cxx:67
 GeneticFitter.cxx:68
 GeneticFitter.cxx:69
 GeneticFitter.cxx:70
 GeneticFitter.cxx:71
 GeneticFitter.cxx:72
 GeneticFitter.cxx:73
 GeneticFitter.cxx:74
 GeneticFitter.cxx:75
 GeneticFitter.cxx:76
 GeneticFitter.cxx:77
 GeneticFitter.cxx:78
 GeneticFitter.cxx:79
 GeneticFitter.cxx:80
 GeneticFitter.cxx:81
 GeneticFitter.cxx:82
 GeneticFitter.cxx:83
 GeneticFitter.cxx:84
 GeneticFitter.cxx:85
 GeneticFitter.cxx:86
 GeneticFitter.cxx:87
 GeneticFitter.cxx:88
 GeneticFitter.cxx:89
 GeneticFitter.cxx:90
 GeneticFitter.cxx:91
 GeneticFitter.cxx:92
 GeneticFitter.cxx:93
 GeneticFitter.cxx:94
 GeneticFitter.cxx:95
 GeneticFitter.cxx:96
 GeneticFitter.cxx:97
 GeneticFitter.cxx:98
 GeneticFitter.cxx:99
 GeneticFitter.cxx:100
 GeneticFitter.cxx:101
 GeneticFitter.cxx:102
 GeneticFitter.cxx:103
 GeneticFitter.cxx:104
 GeneticFitter.cxx:105
 GeneticFitter.cxx:106
 GeneticFitter.cxx:107
 GeneticFitter.cxx:108
 GeneticFitter.cxx:109
 GeneticFitter.cxx:110
 GeneticFitter.cxx:111
 GeneticFitter.cxx:112
 GeneticFitter.cxx:113
 GeneticFitter.cxx:114
 GeneticFitter.cxx:115
 GeneticFitter.cxx:116
 GeneticFitter.cxx:117
 GeneticFitter.cxx:118
 GeneticFitter.cxx:119
 GeneticFitter.cxx:120
 GeneticFitter.cxx:121
 GeneticFitter.cxx:122
 GeneticFitter.cxx:123
 GeneticFitter.cxx:124
 GeneticFitter.cxx:125
 GeneticFitter.cxx:126
 GeneticFitter.cxx:127
 GeneticFitter.cxx:128
 GeneticFitter.cxx:129
 GeneticFitter.cxx:130
 GeneticFitter.cxx:131
 GeneticFitter.cxx:132
 GeneticFitter.cxx:133
 GeneticFitter.cxx:134
 GeneticFitter.cxx:135
 GeneticFitter.cxx:136
 GeneticFitter.cxx:137
 GeneticFitter.cxx:138
 GeneticFitter.cxx:139
 GeneticFitter.cxx:140
 GeneticFitter.cxx:141
 GeneticFitter.cxx:142
 GeneticFitter.cxx:143
 GeneticFitter.cxx:144
 GeneticFitter.cxx:145
 GeneticFitter.cxx:146
 GeneticFitter.cxx:147
 GeneticFitter.cxx:148
 GeneticFitter.cxx:149
 GeneticFitter.cxx:150
 GeneticFitter.cxx:151
 GeneticFitter.cxx:152
 GeneticFitter.cxx:153
 GeneticFitter.cxx:154
 GeneticFitter.cxx:155
 GeneticFitter.cxx:156
 GeneticFitter.cxx:157
 GeneticFitter.cxx:158
 GeneticFitter.cxx:159
 GeneticFitter.cxx:160
 GeneticFitter.cxx:161
 GeneticFitter.cxx:162
 GeneticFitter.cxx:163
 GeneticFitter.cxx:164
 GeneticFitter.cxx:165
 GeneticFitter.cxx:166
 GeneticFitter.cxx:167
 GeneticFitter.cxx:168
 GeneticFitter.cxx:169
 GeneticFitter.cxx:170
 GeneticFitter.cxx:171
 GeneticFitter.cxx:172
 GeneticFitter.cxx:173
 GeneticFitter.cxx:174
 GeneticFitter.cxx:175