00001 #include "ECF_base.h"
00002
00003 const int RANDOM_GENOTYPE = 0;
00004 const int ALL_GENOTYPES = 1;
00005
00006
00007 void Crossover::registerParameters(StateP state)
00008 {
00009 state->getRegistry()->registerEntry("crossover.genotypes", (voidP) new std::string("random"), ECF::STRING);
00010 state->getRegistry()->registerEntry("crossover.protected", (voidP) new std::string(""), ECF::STRING);
00011 }
00012
00013
00014 bool Crossover::initialize(StateP state)
00015 {
00016 state_ = state;
00017 protectedGenotypes_.clear();
00018 protectedGenotypes_.insert(protectedGenotypes_.begin(), operators.size(), false);
00019 opProb.clear();
00020
00021 voidP sptr = state->getRegistry()->getEntry("crossover.genotypes");
00022 std::string crxGen = *((std::string*)sptr.get());
00023
00024 crxGenotypes_ = RANDOM_GENOTYPE;
00025 if(crxGen == "all")
00026 crxGenotypes_ = ALL_GENOTYPES;
00027 else if(crxGen == "random")
00028 crxGenotypes_ = RANDOM_GENOTYPE;
00029 else
00030 state->getLogger()->log(1, "Warning: invalid parameter value (key: crossover.genotypes)");
00031
00032
00033 std::stringstream ss;
00034 sptr = state->getRegistry()->getEntry("crossover.protected");
00035 ss << *((std::string*) sptr.get());
00036 uint genId;
00037 while(ss >> genId) {
00038 if(genId >= protectedGenotypes_.size()) {
00039 state->getLogger()->log(1, "Error: invalid genotype index (key: crossover.protected)!");
00040 throw("");
00041 }
00042 protectedGenotypes_[genId] = true;
00043 }
00044
00045
00046 for(uint gen = 0; gen < operators.size(); gen++) {
00047 uint nOps = (uint) operators[gen].size();
00048
00049 if(nOps == 0) {
00050 protectedGenotypes_[gen] = true;
00051 std::vector<double> empty;
00052 opProb.push_back(empty);
00053 break;
00054 }
00055 for(uint i = 0; i < nOps; i++) {
00056 operators[gen][i]->state_ = state;
00057 operators[gen][i]->initialize(state);
00058 }
00059
00060 std::vector<double> probs(nOps);
00061 probs[0] = operators[gen][0]->probability_;
00062 for(uint i = 1; i < nOps; i++) {
00063 probs[i] = probs[i - 1] + operators[gen][i]->probability_;
00064 }
00065 if(probs[nOps - 1] == 0)
00066 probs[0] = -1;
00067 else
00068 if(probs[nOps - 1] != 1) {
00069 double normal = probs[nOps - 1];
00070 state->getLogger()->log(1, "Warning: " + operators[gen][0]->myGenotype_->getName() +
00071 " crossover operators: cumulative probability not equal to 1 (sum = " + dbl2str(normal) + ")");
00072 for(uint i = 0; i < probs.size(); i++)
00073 probs[i] /= normal;
00074 }
00075 opProb.push_back(probs);
00076 }
00077 return true;
00078 }
00079
00080
00087 bool Crossover::mate(IndividualP ind1, IndividualP ind2, IndividualP child)
00088 {
00089 child->fitness->setInvalid();
00090
00091
00092 if(ind1 == child) {
00093 ind1 = (IndividualP) ind1->copy();
00094 }
00095 if(ind2 == child) {
00096 ind2 = (IndividualP) ind2->copy();
00097 }
00098
00099
00100
00101
00102 if(crxGenotypes_ == RANDOM_GENOTYPE) {
00103 uint iGenotype = state_->getRandomizer()->getRandomInteger((int)ind1->size());
00104 if(protectedGenotypes_[iGenotype])
00105 return false;
00106
00107 for(uint i = 0; i < iGenotype; i++)
00108 child->at(i) = (GenotypeP) ind1->at(i)->copy();
00109 for(uint i = iGenotype + 1; i < child->size(); i++)
00110 child->at(i) = (GenotypeP) ind2->at(i)->copy();
00111
00112 uint iOperator;
00113 if(opProb[iGenotype][0] < 0)
00114 iOperator = state_->getRandomizer()->getRandomInteger((int)operators[iGenotype].size());
00115 else {
00116 double random = state_->getRandomizer()->getRandomDouble();
00117 iOperator = 0;
00118 while(opProb[iGenotype][iOperator] < random)
00119 iOperator++;
00120 }
00121 operators[iGenotype][iOperator]->mate(ind1->at(iGenotype), ind2->at(iGenotype), child->at(iGenotype));
00122 }
00123
00124 else if(crxGenotypes_ == ALL_GENOTYPES) {
00125 for(uint iGenotype = 0; iGenotype < ind1->size(); iGenotype++) {
00126 if(protectedGenotypes_[iGenotype])
00127 continue;
00128
00129 uint iOperator;
00130 if(opProb[iGenotype][0] < 0)
00131 iOperator = state_->getRandomizer()->getRandomInteger((int)operators[iGenotype].size());
00132 else {
00133 double random = state_->getRandomizer()->getRandomDouble();
00134 iOperator = 0;
00135 while(opProb[iGenotype][iOperator] < random)
00136 iOperator++;
00137 }
00138 operators[iGenotype][iOperator]->mate(ind1->at(iGenotype), ind2->at(iGenotype), child->at(iGenotype));
00139 }
00140 }
00141 return true;
00142 }