Example of SimpleGA
This example load a file called 'ga.conf' where it read the configurations.
A template for ga.conf is the following:
[COMMON] randomSeed = 25
[GA] type = SimpleGA numThreads = 2 ### number of threads to use ngenerations = 200
[GA/EVALUATION] type = FitnessFunction ### Custom settings of ga1 example ### Choose among: square, abs, mexhat functionTarget = square
[GA/GENOME] type = Genome nindividuals = 100
[GA/GENOME/GENOTYPE] ### Choose between SignedRange and Real type = SignedRange ngenes = 2 ### Parameters for SignedRange nbits = 8 maxValue = 20 ### Parameters for Real # maxValue = +20 # minValue = -20
[GA/REPRODUCTION] type = FixedSize crossoverRate = 0 elitism = false nelited = 10
[GA/REPRODUCTION/CROSSOVER] type = OnePoint ## OnePoint crossover doesn't need any parameter
[GA/REPRODUCTION/MUTATION] type = RandomFloat ### Choose between FlipBit and RandomFloat mutation_rate = 0.015
[GA/REPRODUCTION/SELECTION] type = DeterministicRank ### Parameters for DeterministicRank nTruncation = 20
#include "gaconfig.h" #include "configuration/configurationparameters.h" #include "configuration/inifilesupport.h" #include "factory/factory.h" #include "core/randomgenerator.h" #include "core/evaluation.h" #include "genotypes/doublegenotype.h" #include "core/genome.h" #include "core/geneticalgo.h" #include <cmath> #include <QDebug> class FitnessFunction : public Evaluation { public: FitnessFunction() : Evaluation() { functype = square; }; // custom configuration // This fitness function can be customized by 'functionTarget' parameter of EVALUATOR group // Possibile functionTarget value are: // - square : compute the sum of square of genes as fitness // - abs : compute the sum of the distances from the id of gene and gene value // Example of use: // // [EVALUATOR] // functionTarget = square virtual void configure( const ConfigurationParameters& params, QString prefix ) { QString ft = params.getValue( prefix + QString( "functionTarget" ) ); if ( ft == "square" ) functype = square; if ( ft == "abs" ) functype = abs; if ( ft == "mexhat" ) functype = mexhat; }; virtual FitnessFunction* clone() const { FitnessFunction* ret = new FitnessFunction(); ret->functype = functype; return ret; }; protected: void init() { }; void step() { double fit = 0.0; //--- calculate the fitness function DoubleGenotype* gen = (DoubleGenotype*)( genotype() ); for( unsigned int i=0; i<gen->numGenes(); i++ ) { switch( functype ) { case square: case mexhat: fit += gen->at(i)*gen->at(i); break; case abs: fit += -fabs( gen->at(i) - i ); break; default: fit = 0; break; } } if ( functype == mexhat ) { fit = cos( sqrt(fit) ) * exp( -fit/40.0 ); } genotype()->setFitness( fit ); evaluationDone(); }; void fini() { }; private: typedef enum { square, abs, mexhat } functionType; functionType functype; }; int main( int argc, char* argv[] ) { Q_UNUSED( argc ); Q_UNUSED( argv ); //--- IMPORTANT !!! You Have To Register your fitness function Factory::getInstance().registerClass<FitnessFunction>( "FitnessFunction" ); //--- Parameters Loaded from file ga.ini (case sensitive) ConfigurationParameters params(true); if (!params.loadParameters("ga.ini")) { qWarning() << "Loading parameters from file ga.ini failed"; return 1; } //--- Initialize the globalRNG with seed if ( params.getValue( "COMMON/randomSeed" ) == "random" ) { globalRNG->setSeed( time(0) ); qDebug() << "Random Seed:" << globalRNG->seed(); } else { globalRNG->setSeed( params.getValue( "COMMON/randomSeed" ).toInt() ); } //--- create and configure the Genetic Algorithm GeneticAlgo* ga = Factory::getInstance().createFromParameter<GeneticAlgo>( params, "GA" ); ga->initialize(); //--- Evolve for all Generations ga->evolve(); //--- print out the best individuals DoubleGenotype* best = (DoubleGenotype*)(ga->genome()->bestGenotype()); qDebug() << "Fitness:" << best->fitness(); qDebug() << best->toString(); for( unsigned int i=0; i<best->numGenes(); i++ ) { qDebug() << "Gene:" << i << "Value:" << best->at(i); } return 0; }