• Main Page
  • Modules
  • Classes
  • Files
  • File List

D:/Projekt/ECF_trunk/ECF/Crossover.cpp

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         "if there are multiple genotypes, which to cross? 'random': a random pair, 'all': all pairs (default: random)");
00014     state->getRegistry()->registerEntry("crossover.protected", (voidP) new std::string(""), ECF::STRING,
00015         "indexes of genotypes (separated by spaces) that are excluded (protected) from crossover (default: none)");
00016 }
00017 
00018 
00022 bool Crossover::initialize(StateP state)
00023 {
00024     state_ = state;
00025     protectedGenotypes_.clear();
00026     protectedGenotypes_.insert(protectedGenotypes_.begin(), operators.size(), false);
00027     opProb.clear();
00028 
00029     voidP sptr = state->getRegistry()->getEntry("crossover.genotypes");
00030     std::string crxGen = *((std::string*)sptr.get());
00031 
00032     crxGenotypes_ = RANDOM_GENOTYPE;
00033     if(crxGen == "all")
00034         crxGenotypes_ = ALL_GENOTYPES;
00035     else if(crxGen == "random")
00036         crxGenotypes_ = RANDOM_GENOTYPE;
00037     else
00038         ECF_LOG_ERROR(state, "Warning: invalid parameter value (key: crossover.genotypes)");
00039 
00040     // read protected genotypes
00041     std::stringstream ss;
00042     sptr = state->getRegistry()->getEntry("crossover.protected");
00043     ss << *((std::string*) sptr.get());
00044     uint genId;
00045     while(ss >> genId) {    // read all the data from string
00046         if(genId >= protectedGenotypes_.size()) {
00047             ECF_LOG_ERROR(state, "Error: invalid genotype index (key: crossover.protected)!");
00048             throw("");
00049         }
00050         protectedGenotypes_[genId] = true;
00051     }
00052 
00053     // initialize operators for all genotypes
00054     for(uint gen = 0; gen < operators.size(); gen++) {
00055         uint nOps = (uint) operators[gen].size();
00056         // if the genotype doesn't define crossover operators
00057         if(nOps == 0) {
00058             protectedGenotypes_[gen] = true;
00059             std::vector<double> empty;
00060             opProb.push_back(empty);
00061             break;
00062         }
00063         for(uint i = 0; i < nOps; i++) {
00064             operators[gen][i]->state_ = state;
00065             operators[gen][i]->initialize(state);
00066         }
00067         // calculate cumulative operator probabilities
00068         std::vector<double> probs(nOps);
00069         probs[0] = operators[gen][0]->probability_;
00070         for(uint i = 1; i < nOps; i++) {
00071             probs[i] = probs[i - 1] + operators[gen][i]->probability_;
00072         }
00073         if(probs[nOps - 1] == 0)
00074             probs[0] = -1;
00075         else
00076             if(probs[nOps - 1] != 1) {
00077                 double normal = probs[nOps - 1];
00078                 ECF_LOG_ERROR(state, "Warning: " + operators[gen][0]->myGenotype_->getName() +
00079                     " crossover operators: cumulative probability not equal to 1 (sum = " + dbl2str(normal) + ")");
00080                 for(uint i = 0; i < probs.size(); i++)
00081                     probs[i] /= normal;
00082             }
00083         opProb.push_back(probs);
00084     }
00085     return true;
00086 }
00087 
00088 
00095 bool Crossover::mate(IndividualP ind1, IndividualP ind2, IndividualP child)
00096 {
00097     child->fitness->setInvalid();
00098     // set crossover context
00099     state_->getContext()->firstParent = ind1;
00100     state_->getContext()->secondParent = ind2;
00101     state_->getContext()->child = child;
00102     ECF_LOG(state_, 5, "Crossover, 1st parent: " + ind1->toString() 
00103         + "\nCrossover, 2nd parent: " + ind2->toString());
00104 
00105     // check if any of the parents is also the child
00106     if(ind1 == child) {
00107         ind1 = (IndividualP) ind1->copy();
00108     }
00109     if(ind2 == child) {
00110         ind2 = (IndividualP) ind2->copy();
00111     }
00112 
00113     // TODO: parameter for genotype exchange (instead of genotype crossover)
00114 
00115     // default: choose radnom genotype pair to crx
00116     if(crxGenotypes_ == RANDOM_GENOTYPE) {
00117         uint iGenotype = state_->getRandomizer()->getRandomInteger((int)ind1->size());
00118         if(protectedGenotypes_[iGenotype])
00119             return false;
00120         // copy unchanged genotypes from parents
00121         for(uint i = 0; i < iGenotype; i++)
00122             child->at(i) = (GenotypeP) ind1->at(i)->copy();
00123         for(uint i = iGenotype + 1; i < child->size(); i++)
00124             child->at(i) = (GenotypeP) ind2->at(i)->copy();
00125         // choose operator
00126         uint iOperator;
00127         if(opProb[iGenotype][0] < 0)
00128             iOperator = state_->getRandomizer()->getRandomInteger((int)operators[iGenotype].size());
00129         else {
00130             double random = state_->getRandomizer()->getRandomDouble();
00131             iOperator = 0;
00132             while(opProb[iGenotype][iOperator] < random)
00133                 iOperator++;
00134         }
00135         operators[iGenotype][iOperator]->mate(ind1->at(iGenotype), ind2->at(iGenotype), child->at(iGenotype));
00136     }
00137     // otherwise: crx all genotypes
00138     else if(crxGenotypes_ == ALL_GENOTYPES) {
00139         for(uint iGenotype = 0; iGenotype < ind1->size(); iGenotype++) {
00140             if(protectedGenotypes_[iGenotype])
00141                 continue;
00142             // choose operator
00143             uint iOperator;
00144             if(opProb[iGenotype][0] < 0)
00145                 iOperator = state_->getRandomizer()->getRandomInteger((int)operators[iGenotype].size());
00146             else {
00147                 double random = state_->getRandomizer()->getRandomDouble();
00148                 iOperator = 0;
00149                 while(opProb[iGenotype][iOperator] < random)
00150                     iOperator++;
00151             }
00152             operators[iGenotype][iOperator]->mate(ind1->at(iGenotype), ind2->at(iGenotype), child->at(iGenotype));
00153         }
00154     }
00155 
00156     ECF_LOG(state_, 5, "Crossover, new individual: " + child->toString());
00157 
00158     return true;
00159 }

Generated on Tue Nov 4 2014 13:04:30 for ECF by  doxygen 1.7.1