T M V A G Aexample

This executable gives an example of a very simple use of the genetic algorithm of TMVA

  • Project : TMVA - a Root-integrated toolkit for multivariate data analysis
  • Package : TMVA
  • Executable: TMVAGAexample

Author: Andreas Hoecker
This notebook tutorial was automatically generated with ROOTBOOK-izer from the macro found in the ROOT repository on Saturday, September 18, 2021 at 09:47 AM.

In [1]:
%%cpp -d
#include <iostream> // Stream declarations
#include <vector>

#include "TMVA/GeneticAlgorithm.h"
#include "TMVA/GeneticFitter.h"
#include "TMVA/IFitterTarget.h"

using namespace std;

using namespace TMVA;

class MyFitness : public IFitterTarget {
    public:
       MyFitness() : IFitterTarget() {
       }

       // the fitness-function goes here
       // the factors are optimized such that the return-value of this function is minimized
       // take care!! the fitness-function must never fail, .. means: you have to prevent
       // the function from reaching undefined values (such as x=0 for 1/x or so)
       //
       // HINT: to use INTEGER variables, it is sufficient to cast the "factor" in the fitness-function
       // to (int). In this case the variable-range has to be chosen +1 ( to get 0..5, take Interval(0,6) )
       // since the introduction of "Interval" ranges can be defined with a third parameter
       // which gives the number of bins within the interval. With that technique discrete values
       // can be achieved easier. The random selection out of this discrete numbers is completely uniform.
       //
       Double_t EstimatorFunction( std::vector<Double_t> & factors ){
           //return (10.- (int)factors.at(0) *factors.at(1) + (int)factors.at(2));
           return (10.- factors.at(0) *factors.at(1) + factors.at(2));

           //return 100.- (10 + factors.at(1)) *factors.at(2)* TMath::Abs( TMath::Sin(factors.at(0)) );
       }
};


class MyGA2nd : public GeneticAlgorithm {
    public:
       MyGA2nd( IFitterTarget& target, Int_t size, vector<Interval*>& ranges ) : GeneticAlgorithm(target,
       size, ranges ){
       }


       // this method has to be activated if one wants to change the behaviour of the evolution
       // works only with the head version
       //void Evolution(){
       //    fSexual = true;
       //    if (fSexual) {
       //       fPopulation.MakeCopies( 5 );
       //       fPopulation.MakeChildren();
       //       fPopulation.NextGeneration();

       //       fPopulation.Mutate( 10, 3, kTRUE, fSpread, fMirror );
       //       fPopulation.Mutate( 40, fPopulation.GetPopulationSize()*3/4 );
       //    } else {
       //       fPopulation.MakeCopies( 3 );
       //       fPopulation.MakeMutants(100,true, 0.1, true);
       //       fPopulation.NextGeneration();
       //    }
      // }
};
In [2]:
std::cout << "Start Test TMVAGAexample" << std::endl
          << "========================" << std::endl
          << "\nEXAMPLE"              << std::endl;
Start Test TMVAGAexample
========================

EXAMPLE

Define all the parameters by their minimum and maximum value in this example 3 parameters are defined.

In [3]:
vector<Interval*> ranges;
ranges.push_back( new Interval(0,15,30) );
ranges.push_back( new Interval(0,13) );
ranges.push_back( new Interval(0,5,3) );

for( std::vector<Interval*>::iterator it = ranges.begin(); it != ranges.end(); it++ ){
   std::cout << " range: " << (*it)->GetMin() << "   " << (*it)->GetMax() << std::endl;
}

IFitterTarget* myFitness = new MyFitness();
 range: 0   15
 range: 0   13
 range: 0   5

Prepare the genetic algorithm with an initial population size of 20 mind: big population sizes will help in searching the domain space of the solution but you have to weight this out to the number of generations the extreme case of 1 generation and populationsize n is equal to a Monte Carlo calculation with n tries

In [4]:
MyGA2nd mg( *myFitness, 100, ranges );

Mg.setparameters( 4, 30, 200, 10,5, 0.95, 0.001 );

In [5]:
#define CONVSTEPS 20
#define CONVCRIT 0.0001
#define SCSTEPS 10
#define SCRATE 5
#define SCFACTOR 0.95

do {
   // prepares the new generation and does evolution
   mg.Init();

   // assess the quality of the individuals
   mg.CalculateFitness();

   mg.GetGeneticPopulation().Print(0);
   std::cout << "---" << std::endl;

   // reduce the population size to the initially defined one
   mg.GetGeneticPopulation().TrimPopulation();

   // tricky thing: control the speed of how fast the "solution space" is searched through
   // this function basically influences the sigma of a gaussian around the actual value
   // of the parameter where the new value will be randomly thrown.
   // when the number of improvements within the last SCSTEPS
   // A) smaller than SCRATE: divide the preset sigma by SCFACTOR
   // B) equal to SCRATE: do nothing
   // C) greater than SCRATE: multiply the preset sigma by SCFACTOR
   // if you don't know what to do, leave it unchanged or even delete this function call
   mg.SpreadControl( SCSTEPS, SCRATE, SCFACTOR );

} while (!mg.HasConverged( CONVSTEPS, CONVCRIT ));  // converged if: fitness-improvement < CONVCRIT within the last CONVSTEPS loops

GeneticGenes* genes = mg.GetGeneticPopulation().GetGenes( 0 );
std::vector<Double_t> gvec;
gvec = genes->GetFactors();
int n = 0;
for( std::vector<Double_t>::iterator it = gvec.begin(); it<gvec.end(); it++ ){
   std::cout << "FACTOR " << n << " : " << (*it) << std::endl;
   n++;
}
                         : fitness: -169.71    f_0: 14.4828     f_1: 12.4085     f_2: 0     
---
                         : fitness: -176.769    f_0: 15     f_1: 12.6179     f_2: 2.5     
---
                         : fitness: -183.167    f_0: 15     f_1: 12.8778     f_2: 0     
---
                         : fitness: -183.167    f_0: 15     f_1: 12.8778     f_2: 0     
---
                         : fitness: -183.167    f_0: 15     f_1: 12.8778     f_2: 0     
---
                         : fitness: -183.167    f_0: 15     f_1: 12.8778     f_2: 0     
---
                         : fitness: -183.779    f_0: 15     f_1: 12.9186     f_2: 0     
---
                         : fitness: -183.779    f_0: 15     f_1: 12.9186     f_2: 0     
---
                         : fitness: -183.823    f_0: 15     f_1: 12.9215     f_2: 0     
---
                         : fitness: -183.823    f_0: 15     f_1: 12.9215     f_2: 0     
---
                         : fitness: -183.823    f_0: 15     f_1: 12.9215     f_2: 0     
---
                         : fitness: -183.823    f_0: 15     f_1: 12.9215     f_2: 0     
---
                         : fitness: -184.677    f_0: 15     f_1: 12.9785     f_2: 0     
---
                         : fitness: -184.677    f_0: 15     f_1: 12.9785     f_2: 0     
---
                         : fitness: -184.677    f_0: 15     f_1: 12.9785     f_2: 0     
---
                         : fitness: -184.677    f_0: 15     f_1: 12.9785     f_2: 0     
---
                         : fitness: -184.677    f_0: 15     f_1: 12.9785     f_2: 0     
---
                         : fitness: -184.677    f_0: 15     f_1: 12.9785     f_2: 0     
---
                         : fitness: -184.677    f_0: 15     f_1: 12.9785     f_2: 0     
---
                         : fitness: -184.677    f_0: 15     f_1: 12.9785     f_2: 0     
---
                         : fitness: -184.677    f_0: 15     f_1: 12.9785     f_2: 0     
---
                         : fitness: -184.677    f_0: 15     f_1: 12.9785     f_2: 0     
---
                         : fitness: -184.677    f_0: 15     f_1: 12.9785     f_2: 0     
---
                         : fitness: -184.677    f_0: 15     f_1: 12.9785     f_2: 0     
---
                         : fitness: -184.862    f_0: 15     f_1: 12.9908     f_2: 0     
---
                         : fitness: -184.862    f_0: 15     f_1: 12.9908     f_2: 0     
---
                         : fitness: -184.99    f_0: 15     f_1: 12.9993     f_2: 0     
---
                         : fitness: -184.99    f_0: 15     f_1: 12.9993     f_2: 0     
---
                         : fitness: -184.99    f_0: 15     f_1: 12.9993     f_2: 0     
---
                         : fitness: -184.99    f_0: 15     f_1: 12.9993     f_2: 0     
---
                         : fitness: -184.99    f_0: 15     f_1: 12.9993     f_2: 0     
---
                         : fitness: -184.99    f_0: 15     f_1: 12.9993     f_2: 0     
---
                         : fitness: -184.99    f_0: 15     f_1: 12.9993     f_2: 0     
---
                         : fitness: -184.99    f_0: 15     f_1: 12.9993     f_2: 0     
---
                         : fitness: -184.99    f_0: 15     f_1: 12.9993     f_2: 0     
---
                         : fitness: -184.99    f_0: 15     f_1: 12.9993     f_2: 0     
---
                         : fitness: -184.99    f_0: 15     f_1: 12.9993     f_2: 0     
---
                         : fitness: -184.99    f_0: 15     f_1: 12.9993     f_2: 0     
---
                         : fitness: -184.99    f_0: 15     f_1: 12.9993     f_2: 0     
---
                         : fitness: -184.99    f_0: 15     f_1: 12.9993     f_2: 0     
---
                         : fitness: -184.99    f_0: 15     f_1: 12.9993     f_2: 0     
---
                         : fitness: -184.99    f_0: 15     f_1: 12.9993     f_2: 0     
---
                         : fitness: -184.99    f_0: 15     f_1: 12.9993     f_2: 0     
---
                         : fitness: -184.99    f_0: 15     f_1: 12.9993     f_2: 0     
---
                         : fitness: -184.99    f_0: 15     f_1: 12.9993     f_2: 0     
---
                         : fitness: -184.99    f_0: 15     f_1: 12.9993     f_2: 0     
---
                         : fitness: -184.99    f_0: 15     f_1: 12.9993     f_2: 0     
---
FACTOR 0 : 15
FACTOR 1 : 12.9993
FACTOR 2 : 0