00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "gaconfig.h"
00021 #include "factory.h"
00022 #include "core/genome.h"
00023 #include "core/selection.h"
00024 #include "core/mutation.h"
00025 #include "core/crossover.h"
00026 #include "reproductions/fixedsize.h"
00027 #include "randomgenerator.h"
00028
00029 namespace farsa {
00030
00031 FixedSize::FixedSize()
00032 : Reproduction() {
00033 sel = 0;
00034 muta = 0;
00035 cross = 0;
00036 isElitism = false;
00037 nElited = 0;
00038 probCrossover = 0;
00039 }
00040
00041 FixedSize::~FixedSize() {
00042
00043 }
00044
00045 Genome* FixedSize::reproduction( const Genome* genome ) {
00046 Q_ASSERT_X( sel != 0,
00047 "FixedSize::reproduction",
00048 "You must set a Selection object before calling this method" );
00049 Q_ASSERT_X( muta != 0,
00050 "FixedSize::reproduction",
00051 "You must set a Mutation object before calling this method" );
00052 Q_ASSERT_X( cross != 0 || probCrossover == 0 ,
00053 "FixedSize::reproduction",
00054 "You must set a Crossover object before calling this method" );
00055 Q_ASSERT_X( nElited >= 0,
00056 "FixedSize::reproduction",
00057 "The number of Elited Genotypes must be greater than zero" );
00058
00059 Genome* ret = new Genome( 0, genome->at(0) );
00060 muta->setGenome( genome );
00061 cross->setGenome( genome );
00062 sel->setGenome( genome );
00063 int left = genome->size();
00064 if ( isElitism ) {
00065 for( int i=0; i<nElited; i++ ) {
00066 ret->append( genome->at(i) );
00067 }
00068 left -= nElited;
00069 }
00070 for( int i=0; i<left; i++ ) {
00071
00072 ret->append( sel->select() );
00073
00074 if ( globalRNG->getBool( probCrossover ) ) {
00075 cross->crossover( ret->last(), sel->select() );
00076 }
00077
00078 muta->mutate( ret->last() );
00079 }
00080 return ret;
00081 }
00082
00083 void FixedSize::setMutation( Mutation* muta ) {
00084 this->muta = muta;
00085 this->muta->setGA( GA() );
00086 }
00087
00088 Mutation* FixedSize::mutation() {
00089 return muta;
00090 }
00091
00092 void FixedSize::setSelection( Selection* sel ) {
00093 this->sel = sel;
00094 this->sel->setGA( GA() );
00095 }
00096
00097 Selection* FixedSize::selection() {
00098 return sel;
00099 }
00100
00101 void FixedSize::setCrossover( Crossover* cross ) {
00102 this->cross = cross;
00103 this->cross->setGA( GA() );
00104 }
00105
00106 Crossover* FixedSize::crossover() {
00107 return cross;
00108 }
00109
00110 void FixedSize::setCrossoverRate( double prob ) {
00111 this->probCrossover = prob;
00112 }
00113
00114 double FixedSize::crossoverRate() {
00115 return probCrossover;
00116 }
00117
00118 void FixedSize::enableElitism( bool enable ) {
00119 isElitism = enable;
00120 }
00121
00122 bool FixedSize::isElitismEnabled() {
00123 return isElitism;
00124 }
00125
00126 void FixedSize::setNumberElited( unsigned int nelited ) {
00127 this->nElited = nelited;
00128 }
00129
00130 int FixedSize::numberElited() {
00131 return nElited;
00132 }
00133
00134 void FixedSize::configure( ConfigurationParameters& params, QString prefix ) {
00135 setMutation( params.getObjectFromGroup<Mutation>( prefix + QString( "MUTATION" ) ) );
00136 setSelection( params.getObjectFromGroup<Selection>( prefix + QString( "SELECTION" ) ) );
00137 setCrossover( params.getObjectFromGroup<Crossover>( prefix + QString( "CROSSOVER" ) ) );
00138 probCrossover = params.getValue( prefix + QString( "crossoverRate" ) ).toDouble();
00139 isElitism = ! (params.getValue( prefix + QString( "elitism" ) ).compare( "true", Qt::CaseInsensitive ) );
00140 nElited = params.getValue( prefix + QString( "nelited" ) ).toInt();
00141 }
00142
00143 void FixedSize::save( ConfigurationParameters& params, QString prefix ) {
00144 params.createParameter( prefix, QString("type"), "FixedSize" );
00145 params.createParameter( prefix, QString("crossoverRate"), QString("%1").arg( probCrossover ) );
00146 params.createParameter( prefix, QString("elitism"), isElitism ? "true" : "false" );
00147 params.createParameter( prefix, QString("nelited"), QString("%1").arg( nElited ) );
00148
00149 if ( mutation() ) {
00150 mutation()->save( params, params.createSubGroup( prefix, "MUTATION" ) );
00151 }
00152
00153 if ( selection() ) {
00154 selection()->save( params, params.createSubGroup( prefix, "SELECTION" ) );
00155 }
00156
00157 if ( crossover() ) {
00158 crossover()->save( params, params.createSubGroup( prefix, "CROSSOVER" ) );
00159 }
00160 }
00161
00162 void FixedSize::describe( QString type ) {
00163 Descriptor d = addTypeDescription( type, "Create a new generation mantaining constant the number of individuals", "It apply the selection, crossover and mutation operators without changing the size of the Genome" );
00164 d.describeReal( "crossoverRate" ).limits( 0, 1 ).def( 0.1 ).help( "The probability to apply the crossover operator" );
00165 d.describeBool( "elitism" ).def( false ).help( "Enable/Disable the elitism" );
00166 d.describeInt( "nelited" ).limits( 0, INT_MAX ).def( 10 ).help( "The number of individual to copy exactly to the new generation; only if elitism is true" );
00167 d.describeSubgroup( "MUTATION" ).type( "Mutation" ).props( IsMandatory ).help( "The mutation operator used to mutate Genotypes" );
00168 d.describeSubgroup( "SELECTION" ).type( "Selection" ).props( IsMandatory ).help( "The selection operator used to select Genotypes for reproduction" );
00169 d.describeSubgroup( "CROSSOVER" ).type( "Crossover" ).props( IsMandatory ).help( "The crossover operator used to generate offsprings from Genotypes" );
00170 }
00171
00172 }