00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "core/mutation.h"
00021 #include "core/geneticalgo.h"
00022 #include "configurationparameters.h"
00023 #include "configurationhelper.h"
00024
00025 namespace farsa {
00026
00027 Mutation::Mutation() {
00028 genomev = 0;
00029 ga = 0;
00030 lastGenMutaRatesChange = 0;
00031
00032
00033 mutaRates[0] = MutationRate();
00034 }
00035
00036 Mutation::~Mutation() {
00037
00038 }
00039
00040 void Mutation::setMutationRate( double rate, int start, int length) {
00041
00042 setMutationRate(rate, rate, 0.0, start, length);
00043 }
00044
00045 void Mutation::setMutationRate( double initialRate, double finalRate, double variation, int start, int length) {
00046
00047 QMutexLocker locker(&mutaRatesMutex);
00048
00049
00050
00051 if (((initialRate > finalRate) && (variation > 0.0)) || ((initialRate < finalRate) && (variation < 0.0))) {
00052 variation = -variation;
00053 }
00054
00055
00056 QMap<int, MutationRate>::iterator iter = mutaRates.begin();
00057 MutationRate current;
00058 while (iter != mutaRates.end()) {
00059 if (iter.key() <= start) {
00060
00061 current = iter.value();
00062
00063 iter++;
00064 } else if ((length <= 0) || (iter.key() <= (start + length))) {
00065
00066
00067
00068 current = iter.value();
00069
00070 QMap<int, MutationRate>::iterator tmp = iter;
00071 iter++;
00072 mutaRates.erase(tmp);
00073 } else {
00074
00075 break;
00076 }
00077 }
00078
00079
00080 MutationRate newRate;
00081 newRate.initial = initialRate;
00082 newRate.final = finalRate;
00083 newRate.variation = variation;
00084 if (ga != NULL) {
00085 newRate.rateForGeneration(ga->generation());
00086 } else {
00087 newRate.mutaRate = initialRate;
00088 }
00089 mutaRates[start] = newRate;
00090 if (length > 0) {
00091
00092 mutaRates[start + length] = current;
00093 }
00094 }
00095
00096 double Mutation::mutationRate( int bit ) {
00097
00098 QMutexLocker locker(&mutaRatesMutex);
00099
00100 if ((ga != NULL) && (ga->generation() != lastGenMutaRatesChange)) {
00101 lastGenMutaRatesChange = ga->generation();
00102 updateMutationRates();
00103 }
00104
00105 return getMutationRateForBit(bit).mutaRate;
00106 }
00107
00108 double Mutation::initialMutationRate( int bit ) {
00109 return getMutationRateForBit(bit).initial;
00110 }
00111
00112 double Mutation::finalMutationRate( int bit ) {
00113 return getMutationRateForBit(bit).final;
00114 }
00115
00116 double Mutation::variationMutationRate( int bit ) {
00117 return getMutationRateForBit(bit).variation;
00118 }
00119
00120 #ifdef __GNUC__
00121 #warning IN Mutation: WE SHOULD ALLOW SETTING MUTATION RATES FOR VARIOUS BITS FROM CONFIGURATION FILE
00122 #endif
00123
00124 void Mutation::configure( ConfigurationParameters& params, QString prefix ) {
00125 double initial_mutation_rate, final_mutation_rate, variation_mutation_rate;
00126
00127
00128
00129
00130 initial_mutation_rate = final_mutation_rate = ConfigurationHelper::getDouble(params, prefix + "mutation_rate", 0.0);
00131 initial_mutation_rate = ConfigurationHelper::getDouble(params, prefix + "initial_mutation_rate", initial_mutation_rate);
00132 final_mutation_rate = ConfigurationHelper::getDouble(params, prefix + "final_mutation_rate", final_mutation_rate);
00133 variation_mutation_rate = ConfigurationHelper::getDouble(params, prefix + "variation_mutation_rate", 0.01);
00134 setMutationRate(initial_mutation_rate, final_mutation_rate, variation_mutation_rate);
00135 if ( mutationRate(0) == 0 ) {
00136 qWarning( "Setting mutation Rate to ZERO!! Check your config file" );
00137 }
00138 }
00139
00140 void Mutation::save( ConfigurationParameters& params, QString prefix ) {
00141
00142
00143
00144 params.createParameter( prefix, QString("type"), "Mutation" );
00145 if (initialMutationRate(0) == finalMutationRate(0)) {
00146 params.createParameter( prefix, QString("mutation_rate"), QString("%1").arg(mutationRate(0)) );
00147 } else {
00148 params.createParameter( prefix, QString("initial_mutation_rate"), QString("%1").arg(initialMutationRate(0)) );
00149 params.createParameter( prefix, QString("final_mutation_rate"), QString("%1").arg(finalMutationRate(0)) );
00150 params.createParameter( prefix, QString("variation_mutation_rate"), QString("%1").arg(variationMutationRate(0)) );
00151 }
00152 }
00153
00154 void Mutation::describe( QString type ) {
00155 Descriptor d = addTypeDescription( type, "Mutation operator" );
00156 d.describeReal( "mutation_rate" ).limits( 0, 1 ).def( 0.05 ).props( IsMandatory ).help( "The probability to apply the mutation operator" );
00157 d.describeReal( "initial_mutation_rate" ).limits( 0, 1 ).def( 0.05 ).help( "The initial probability to apply the mutation operator; this has to be used in combination with final_mutation_rate and variation_mutation_rate to implement a probability of mutation that vary over generations" );
00158 d.describeReal( "final_mutation_rate" ).limits( 0, 1 ).def( 0.05 ).help( "The final probability to apply the mutation operator; this has to be used in combination with initial_mutation_rate and variation_mutation_rate to implement a probability of mutation that vary over generations" );
00159 d.describeReal( "variation_mutation_rate" ).limits( 0, 1 ).def( 0.05 ).help( "The amount of change applied to the current probability to apply the mutation operator in the next generation; this has to be used in combination with initial_mutation_rate and final_mutation_rate to implement a probability of mutation that vary over generations" );
00160 }
00161
00162 void Mutation::updateMutationRates() {
00163 for (QMap<int, MutationRate>::iterator iter = mutaRates.begin(); iter != mutaRates.end(); iter++) {
00164 if (ga != NULL) {
00165 iter.value().rateForGeneration(ga->generation());
00166 } else {
00167 iter.value().mutaRate = iter.value().initial;
00168 }
00169 }
00170 }
00171
00172 void Mutation::MutationRate::rateForGeneration(unsigned int gen) {
00173 mutaRate = initial + variation * double(gen);
00174 if (((initial > final) && (mutaRate < final)) || ((initial < final) && (mutaRate > final))) {
00175 mutaRate = final;
00176 }
00177 }
00178
00179 #ifdef __GNUC__
00180 #warning WE SHOULD TRY TO MAKE Mutation::getMutationRateForBit MORE EFFICIENT
00181 #endif
00182
00183 const Mutation::MutationRate& Mutation::getMutationRateForBit( int bit ) const {
00184
00185 if (bit < 0) {
00186 bit = 0;
00187 }
00188
00189
00190 QMap<int, MutationRate>::const_iterator iter = mutaRates.constBegin();
00191 for (; (iter != mutaRates.constEnd()) && (iter.key() <= bit); iter++);
00192
00193
00194 iter--;
00195 return iter.value();
00196 }
00197
00198 }