// @(#)root/tmva $Id$ // 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 - 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 #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& 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& pars ) { // Execute fitting Log() << kINFO << " 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; iGetFactors(), ga.GetGeneticPopulation().GetGenes(i)->GetFitness() ); } } while (!ga.HasConverged( fNsteps, fConvCrit )); timer.DrawProgressBar( 100*(cycle+1) ); ga.GetGeneticPopulation().Sort(); for ( Int_t i = 0; iGetFactors(), 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; }