00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "factory.h"
00021 #include "gas/stefanosteadystatega.h"
00022 #include "core/reproduction.h"
00023 #include "core/genome.h"
00024 #include "core/evaluation.h"
00025 #include "logger.h"
00026 #include <QThreadPool>
00027 #include <QtConcurrentMap>
00028 using namespace QtConcurrent;
00029
00030 namespace farsa {
00031
00032 StefanoSteadyStateGA::StefanoSteadyStateGA() :
00033 GeneticAlgo(),
00034 fitfunc(NULL),
00035 muta(NULL),
00036 curPhase(initParent),
00037 curGenotype(0),
00038 isInitialized(false),
00039 isFinalized(true),
00040 numEvaluations(),
00041 cumulatedFitness(),
00042 offspring(NULL)
00043 {
00044 }
00045
00046 StefanoSteadyStateGA::~StefanoSteadyStateGA() {
00047 delete fitfunc;
00048 delete muta;
00049 }
00050
00051 void StefanoSteadyStateGA::configure( ConfigurationParameters& params, QString prefix ) {
00052 setGenome( params.getObjectFromGroup<Genome>( prefix + QString( "GENOME" ) ) );
00053 setEvaluation( params.getObjectFromGroup<Evaluation>( prefix + QString( "EVALUATION" ) ) );
00054 fitfunc->setGenome( genome() );
00055 setMutation( params.getObjectFromGroup<Mutation>( prefix + QString( "MUTATION" ) ) );
00056 setNumGenerations( params.getValue( prefix + QString( "ngenerations" ) ).toInt() );
00057 if ( numGenerations() == 0 ) {
00058 Logger::warning( "StefanoSteadyStateGA: Setting number of Generations to ZERO!! Check your config file" );
00059 }
00060 }
00061
00062 void StefanoSteadyStateGA::save( ConfigurationParameters& params, QString prefix ) {
00063 params.createParameter( prefix, QString("type"), "StefanoSteadyStateGA" );
00064 params.createParameter( prefix, QString("ngenerations"), QString("%1").arg( numGenerations() ) );
00065
00066 fitfunc->save( params, params.createSubGroup( prefix, "EVALUATION" ) );
00067
00068 mutation()->save( params, params.createSubGroup( prefix, "MUTATION" ) );
00069
00070 genome()->save( params, params.createSubGroup( prefix, "GENOME" ) );
00071 }
00072
00073 void StefanoSteadyStateGA::describe( QString type ) {
00074 Descriptor d = addTypeDescription( type, "A variant of Steady State Genetic Algorithm developed by Stefano Nolfi" );
00075 d.describeInt( "numThreads" ).limits( 1, 32 ).help( "Number of threads to parallelize the evaluation of individuals" );
00076 d.describeInt( "ngenerations" ).limits( 1, MaxInteger ).def( 1000 ).help( "Number of the generations of the evolutionary process" );
00077 d.describeSubgroup( "EVALUATION" ).type( "Evaluation" ).props( IsMandatory ).help( "Object that calculate the fitness", "Create a subclass of Evalution and code your custom fitness function" );
00078 d.describeSubgroup( "MUTATION").type( "Mutation" ).props( IsMandatory ).help( "Object that mutate the genotype of an individual" );
00079 d.describeSubgroup( "GENOME" ).type( "Genome" ).props( IsMandatory ).help( "Object containing the individuals under evolution" );
00080 }
00081
00082 void StefanoSteadyStateGA::setEvaluation( Evaluation* fitfunc ) {
00083 this->fitfunc = fitfunc;
00084 this->fitfunc->setGA( this );
00085 }
00086
00087 Evaluation* StefanoSteadyStateGA::evaluationPrototype()
00088 {
00089 return fitfunc;
00090 }
00091
00092 QVector<Evaluation*> StefanoSteadyStateGA::evaluationPool() {
00093
00094 QVector<Evaluation*> ev;
00095 ev.append(fitfunc);
00096 return ev;
00097 }
00098
00099 void StefanoSteadyStateGA::setMutation( Mutation* mutation ) {
00100 this->muta = mutation;
00101 this->muta->setGA( this );
00102 }
00103
00104 Mutation* StefanoSteadyStateGA::mutation() {
00105 return muta;
00106 }
00107
00108 void StefanoSteadyStateGA::initialize() {
00109 if ( isInitialized && !isFinalized ) return;
00110 Q_ASSERT_X( fitfunc != 0 ,
00111 "StefanoSteadyStateGA::initialize",
00112 "You have to setup the Evaluation object of StefanoSteadyStateGA (Fitness Function)" );
00113 Q_ASSERT_X( muta !=0 ,
00114 "StefanoSteadyStateGA::initialize",
00115 "You have to setup the Mutation operator of StefanoSteadyStateGA" );
00116
00117 isInitialized = true;
00118 isFinalized = false;
00119 setGeneration(0);
00120 curPhase = initParent;
00121 curGenotype = 0;
00122 evolutionEnd = false;
00123 evaluationDone = false;
00124 delete offspring;
00125 offspring = NULL;
00126
00127
00128 muta->setGenome(genome());
00129 fitfunc->setGenome(genome());
00130 numEvaluations.fill(0, genome()->size());
00131 cumulatedFitness.fill(0.0, genome()->size());
00132 }
00133
00134 void StefanoSteadyStateGA::gaStep() {
00135 switch (curPhase) {
00136 case initParent:
00137 {
00138 fitfunc->initialize(genome()->at(curGenotype));
00139 curPhase = evalParent;
00140 }
00141 break;
00142 case evalParent:
00143 {
00144 fitfunc->evaluateStep();
00145 if (fitfunc->isEvaluationDone()) {
00146 fitfunc->finalize();
00147 cumulatedFitness[curGenotype] += fitfunc->genotype()->fitness();
00148 numEvaluations[curGenotype]++;
00149 fitfunc->genotype()->setRank(cumulatedFitness[curGenotype] / double(numEvaluations[curGenotype]));
00150 curPhase = initOffspring;
00151 }
00152 }
00153 break;
00154 case initOffspring:
00155 {
00156
00157 delete offspring;
00158 offspring = genome()->at(curGenotype)->clone();
00159 muta->mutate(offspring);
00160 fitfunc->initialize(offspring);
00161 curPhase = evalOffspring;
00162 }
00163 break;
00164 case evalOffspring:
00165 {
00166 fitfunc->evaluateStep();
00167 if (fitfunc->isEvaluationDone()) {
00168 fitfunc->finalize();
00169 offspring->setRank(offspring->fitness());
00170 curPhase = compareOffspring;
00171 }
00172 }
00173 break;
00174 case compareOffspring:
00175 {
00176
00177
00178 unsigned int worstGenome = 0;
00179 double worstGenomeFitness = genome()->at(0)->rank();
00180 for (unsigned int i = 1; i < genome()->size(); i++) {
00181 if (numEvaluations[i] == 0) {
00182 continue;
00183 }
00184 if (genome()->at(i)->rank() < worstGenomeFitness) {
00185 worstGenome = i;
00186 worstGenomeFitness = genome()->at(i)->rank();
00187 }
00188 }
00189
00190 if (worstGenomeFitness < offspring->rank()) {
00191 *(genome()->at(worstGenome)) = *offspring;
00192 cumulatedFitness[worstGenome] = offspring->rank();
00193 numEvaluations[worstGenome] = 1;
00194 }
00195 if (curGenotype < (genome()->size() - 1)) {
00196 curGenotype++;
00197 curPhase = initParent;
00198 } else {
00199 evaluationDone = true;
00200 curPhase = nextGeneration;
00201 }
00202 }
00203 break;
00204 case nextGeneration:
00205 {
00206
00207 updateStats();
00208 evaluationDone = false;
00209 if (generation() < numGens) {
00210 curPhase = initParent;
00211 setGeneration( generation()+1 );
00212 curGenotype = 0;
00213 } else {
00214 curPhase = endEvolution;
00215 }
00216 }
00217 break;
00218 case endEvolution:
00219 {
00220 finalize();
00221 }
00222 break;
00223 default:
00224 qFatal("Default switch in StefanoSteadyStateGA::gaStep");
00225 break;
00226 }
00227 }
00228
00229 void StefanoSteadyStateGA::skipEvaluation() {
00230
00231 evaluationDone = true;
00232 curPhase = nextGeneration;
00233 }
00234
00235 void StefanoSteadyStateGA::finalize() {
00236 if ( isFinalized && !isInitialized ) return;
00237
00238 isInitialized = false;
00239 isFinalized = true;
00240 evolutionEnd = true;
00241 delete offspring;
00242 offspring = NULL;
00243
00244
00245
00246
00247 qSort( genome()->begin(), genome()->end(), Genotype::rankGreaterThanComparator );
00248 }
00249
00250 }