00001 #include "ECF_base.h"
00002
00003 const int RANDOM_GENOTYPE = 0;
00004 const int ALL_GENOTYPES = 1;
00005
00006
00010 double Mutation::getIndMutProb()
00011 {
00012 return indMutProb_;
00013 }
00014
00015
00019 double Mutation::setIndMutProb(double newProb)
00020 {
00021 if(newProb >= 0 && newProb <= 1)
00022 indMutProb_ = newProb;
00023 return indMutProb_;
00024 }
00025
00026
00030 void Mutation::registerParameters(StateP state)
00031 {
00032 state->getRegistry()->registerEntry("mutation.indprob", (voidP) new double(0.3), ECF::DOUBLE,
00033 "individual mutation probability (unless the algorithm overrides it) (default: 0.3)");
00034
00035 state->getRegistry()->registerEntry("mutation.genotypes", (voidP) new std::string("random"), ECF::STRING,
00036 "if there are multiple genotypes, which to mutate? 'random': a random one, all: mutate all (default: random)");
00037 state->getRegistry()->registerEntry("mutation.protected", (voidP) new std::string(""), ECF::STRING,
00038 "indexes of genotypes (separated by spaces) that are excluded (protected) from mutation (default: none)");
00039 }
00040
00041
00045 bool Mutation::initialize(StateP state)
00046 {
00047 state_ = state;
00048 protectedGenotypes_.clear();
00049 protectedGenotypes_.insert(protectedGenotypes_.begin(), operators.size(), false);
00050 opProb.clear();
00051
00052 voidP sptr = state->getRegistry()->getEntry("mutation.indprob");
00053 indMutProb_ = *((double*)sptr.get());
00054
00055 sptr = state->getRegistry()->getEntry("mutation.geneprob");
00056
00057
00058
00059
00060 sptr = state->getRegistry()->getEntry("mutation.genotypes");
00061 std::string mutGen = *((std::string*)sptr.get());
00062
00063 mutateGenotypes_ = RANDOM_GENOTYPE;
00064 if(mutGen == "random")
00065 mutateGenotypes_ = RANDOM_GENOTYPE;
00066 else if(mutGen == "all")
00067 mutateGenotypes_ = ALL_GENOTYPES;
00068 else
00069 ECF_LOG_ERROR(state, "Warning: invalid parameter value (key: mutation.genotypes)");
00070
00071
00072 std::stringstream ss;
00073 sptr = state->getRegistry()->getEntry("mutation.protected");
00074 ss << *((std::string*) sptr.get());
00075 uint genId;
00076 while(ss >> genId) {
00077 if(genId >= protectedGenotypes_.size()) {
00078 ECF_LOG_ERROR(state, "Error: invalid genotype index (key: mutation.protected)!");
00079 throw("");
00080 }
00081 protectedGenotypes_[genId] = true;
00082 }
00083
00084
00085 for(uint gen = 0; gen < operators.size(); gen++) {
00086 uint nOps = (uint) operators[gen].size();
00087
00088 if(nOps == 0) {
00089 protectedGenotypes_[gen] = true;
00090 std::vector<double> empty;
00091 opProb.push_back(empty);
00092 break;
00093 }
00094 for(uint i = 0; i < nOps; i++) {
00095 operators[gen][i]->state_ = state;
00096 operators[gen][i]->initialize(state);
00097 }
00098
00099 std::vector<double> probs(nOps);
00100 probs[0] = operators[gen][0]->probability_;
00101 for(uint i = 1; i < nOps; i++) {
00102 probs[i] = probs[i - 1] + operators[gen][i]->probability_;
00103 }
00104 if(probs[nOps - 1] == 0) {
00105 std::vector<double> none(1);
00106 none[0] = -1;
00107 opProb.push_back(none);
00108 } else {
00109 if(probs[nOps - 1] != 1) {
00110 double normal = probs[nOps - 1];
00111 ECF_LOG_ERROR(state, "Warning: " + operators[gen][0]->myGenotype_->getName() +
00112 " mutation operators: cumulative probability not equal to 1 (sum = " + dbl2str(normal) + ")");
00113 for(uint i = 0; i < probs.size(); i++)
00114 probs[i] /= normal;
00115 }
00116 opProb.push_back(probs);
00117 }
00118 }
00119 return true;
00120 }
00121
00122
00133 uint Mutation::mutation(const std::vector<IndividualP> &pool)
00134 {
00135 uint mutated = 0;
00136 for(uint i = 0; i < pool.size(); i++) {
00137 if(state_->getRandomizer()->getRandomDouble() <= indMutProb_) {
00138 mutated++;
00139 mutate(pool[i]);
00140 }
00141 }
00142
00143 return mutated;
00144 }
00145
00146
00153 bool Mutation::mutate(IndividualP ind)
00154 {
00155 ind->fitness->setInvalid();
00156
00157 state_->getContext()->mutatedIndividual = ind;
00158 ECF_LOG(state_, 5, "Mutating individual: " + ind->toString());
00159 currentInd = ind;
00160
00161
00162 if(mutateGenotypes_ == RANDOM_GENOTYPE) {
00163 uint iGenotype = state_->getRandomizer()->getRandomInteger((int)ind->size());
00164 if(protectedGenotypes_[iGenotype])
00165 return false;
00166
00167 uint iOperator;
00168 if(opProb[iGenotype][0] < 0)
00169 iOperator = state_->getRandomizer()->getRandomInteger((int)operators[iGenotype].size());
00170 else {
00171 double random = state_->getRandomizer()->getRandomDouble();
00172 iOperator = 0;
00173 while(opProb[iGenotype][iOperator] < random)
00174 iOperator++;
00175 }
00176 operators[iGenotype][iOperator]->mutate(ind->at(iGenotype));
00177 }
00178
00179
00180 else if(mutateGenotypes_ == ALL_GENOTYPES) {
00181 for(uint iGenotype = 0; iGenotype < ind->size(); iGenotype++) {
00182 if(protectedGenotypes_[iGenotype])
00183 continue;
00184
00185 uint iOperator;
00186 if(opProb[iGenotype][0] < 0)
00187 iOperator = state_->getRandomizer()->getRandomInteger((int)operators[iGenotype].size());
00188 else {
00189 double random = state_->getRandomizer()->getRandomDouble();
00190 iOperator = 0;
00191 while(opProb[iGenotype][iOperator] < random)
00192 iOperator++;
00193 }
00194 operators[iGenotype][0]->mutate(ind->at(iGenotype));
00195 }
00196 }
00197
00198 ECF_LOG(state_, 5, "Mutated individual: " + ind->toString());
00199
00200 return true;
00201 }
00202