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