/*! * \brief Apply the operation on a deme in the given context. * \param ioDeme Reference to the deme on which the operation takes place. * \param ioContext Evolutionary context of the operation. */ void GenerationalOp::operate(Deme& ioDeme, Context& ioContext) { Beagle_StackTraceBeginM(); Beagle_NonNullPointerAssertM(getRootNode()); Beagle_NonNullPointerAssertM(mElitismKeepSize); Beagle_ValidateParameterM(mElitismKeepSize->getWrappedValue() <= ioDeme.size(), "ec.elite.keepsize", "The elistism keepsize must be less than the deme size!"); Beagle_LogTraceM( ioContext.getSystem().getLogger(), "Processing using generational replacement strategy the " << uint2ordinal(ioContext.getDemeIndex()+1) << " deme" ); Beagle_LogTraceM(ioContext.getSystem().getLogger(), (*this)); RouletteT<unsigned int> lRoulette; buildRoulette(lRoulette, ioContext); Individual::Bag lOffsprings; const Factory& lFactory = ioContext.getSystem().getFactory(); if(mElitismKeepSize->getWrappedValue() > 0) { History::Handle lHistory = castHandleT<History>(ioContext.getSystem().haveComponent("History")); std::make_heap(ioDeme.begin(), ioDeme.end(), IsLessPointerPredicate()); for(unsigned int i=0; i<mElitismKeepSize->getWrappedValue(); ++i) { std::string lIndividualType = ioDeme[0]->getType(); Individual::Alloc::Handle lIndividualAlloc = castHandleT<Individual::Alloc>(lFactory.getAllocator(lIndividualType)); Individual::Handle lEliteIndiv = castHandleT<Individual>(lIndividualAlloc->allocate()); lEliteIndiv->copy(*ioDeme[0], ioContext.getSystem()); lOffsprings.push_back(lEliteIndiv); if(lHistory != NULL) { HistoryID::Handle lHID = castHandleT<HistoryID>(ioDeme[0]->getMember("HistoryID")); std::vector<HistoryID> lParent; if(lHID != NULL) lParent.push_back(*lHID); lHistory->allocateNewID(*lEliteIndiv); lHistory->trace(ioContext, lParent, lEliteIndiv, getName(), "elitism"); } std::pop_heap(ioDeme.begin(), (ioDeme.end()-i), IsLessPointerPredicate()); } } for(unsigned int i=mElitismKeepSize->getWrappedValue(); i<ioDeme.size(); ++i) { unsigned int lIndexBreeder = lRoulette.select(ioContext.getSystem().getRandomizer()); BreederNode::Handle lSelectedBreeder=getRootNode(); for(unsigned int j=0; j<lIndexBreeder; ++j) lSelectedBreeder=lSelectedBreeder->getNextSibling(); Beagle_NonNullPointerAssertM(lSelectedBreeder); Beagle_NonNullPointerAssertM(lSelectedBreeder->getBreederOp()); Individual::Handle lBredIndiv = lSelectedBreeder->getBreederOp()->breed(ioDeme, lSelectedBreeder->getFirstChild(), ioContext); Beagle_NonNullPointerAssertM(lBredIndiv); lOffsprings.push_back(lBredIndiv); } for(unsigned int j=0; j<lOffsprings.size(); ++j) ioDeme[j] = lOffsprings[j]; Beagle_StackTraceEndM(); }
/*! * \brief Apply the crossover operation on a breeding pool, returning a mated individual. * \param inBreedingPool Breeding pool to use for the crossover operation. * \param inChild Node handle associated to child node in the breeder tree. * \param ioContext Evolutionary context of the crossover operation. * \return Mated individual. */ Individual::Handle CrossoverOp::breed(Individual::Bag& inBreedingPool, BreederNode::Handle inChild, Context& ioContext) { Beagle_StackTraceBeginM(); Context::Alloc::Handle lContextAlloc = castHandleT<Context::Alloc>(ioContext.getSystem().getFactory().getConceptAllocator("Context")); Context::Handle lContext2 = castHandleT<Context>(lContextAlloc->clone(ioContext)); Beagle_NonNullPointerAssertM(inChild); Beagle_NonNullPointerAssertM(inChild->getBreederOp()); Individual::Handle lIndiv1 = inChild->getBreederOp()->breed(inBreedingPool, inChild->getFirstChild(), ioContext); Beagle_NonNullPointerAssertM(inChild->getNextSibling()); Beagle_NonNullPointerAssertM(inChild->getNextSibling()->getBreederOp()); Individual::Handle lIndiv2 = inChild->getNextSibling()->getBreederOp()->breed(inBreedingPool, inChild->getNextSibling()->getFirstChild(), *lContext2); Beagle_LogVerboseM( ioContext.getSystem().getLogger(), std::string("Mating the ")+uint2ordinal(ioContext.getIndividualIndex()+1)+ std::string(" individual with the ")+uint2ordinal(lContext2->getIndividualIndex()+1)+ " individual" ); if((lIndiv1 != NULL) && (lIndiv2 != NULL)) { bool lMated = mate(*lIndiv1, ioContext, *lIndiv2, *lContext2); if(lMated) { if(lIndiv1->getFitness() != NULL) lIndiv1->getFitness()->setInvalid(); if(lIndiv2->getFitness() != NULL) lIndiv2->getFitness()->setInvalid(); History::Handle lHistory = castHandleT<History>(ioContext.getSystem().haveComponent("History")); if(lHistory != NULL) { std::vector<HistoryID> lParents; HistoryID::Handle lHID1 = castHandleT<HistoryID>(lIndiv1->getMember("HistoryID")); if(lHID1 != NULL) lParents.push_back(*lHID1); HistoryID::Handle lHID2 = castHandleT<HistoryID>(lIndiv2->getMember("HistoryID")); if(lHID2 != NULL) lParents.push_back(*lHID2); lHistory->incrementHistoryVar(*lIndiv1); lHistory->trace(ioContext, lParents, lIndiv1, getName(), "crossover"); } } } return lIndiv1; Beagle_StackTraceEndM(); }
/*! * \brief Apply the breeding operation on a breeding pool, returning a bred individual. * \param inBreedingPool * \param inChild * \param ioContext Evolutionary context of the breeding operation. * \return Bred individual. */ Individual::Handle InitializationOp::breed(Individual::Bag& inBreedingPool, BreederNode::Handle inChild, Context& ioContext) { Beagle_StackTraceBeginM(); const Factory& lFactory = ioContext.getSystem().getFactory(); Individual::Alloc::Handle lIndivAlloc = castHandleT<Individual::Alloc>(lFactory.getConceptAllocator("Individual")); Individual::Handle lNewIndiv = castHandleT<Individual>(lIndivAlloc->allocate()); initIndividual(*lNewIndiv, ioContext); if(lNewIndiv->getFitness() != NULL) lNewIndiv->getFitness()->setInvalid(); History::Handle lHistory = castHandleT<History>(ioContext.getSystem().haveComponent("History")); if(lHistory != NULL) { lHistory->incrementHistoryVar(*lNewIndiv); lHistory->trace(ioContext, std::vector<HistoryID>(), lNewIndiv, getName(), "initialization"); } ioContext.setIndividualHandle(lNewIndiv); return lNewIndiv; Beagle_StackTraceEndM(); }
/*! * \brief Apply the evaluation process on the invalid individuals of the deme. * \param ioDeme Deme to process. * \param ioContext Context of the evolution. */ void EvaluationMultipleOp::operate(Deme& ioDeme, Context& ioContext) { Beagle_StackTraceBeginM(); Beagle_LogTraceM( ioContext.getSystem().getLogger(), "Evaluating the fitness of the individuals in the " << uint2ordinal(ioContext.getDemeIndex()+1) << " deme" ); Beagle_AssertM( ioDeme.size()!=0 ); // Prepare stats prepareStats(ioDeme,ioContext); // Generate a vector of indicies into the population std::vector<unsigned int> lEvalVector; for(unsigned int i=0; i<ioDeme.size(); i++) { if((ioDeme[i]->getFitness() == NULL) || (ioDeme[i]->getFitness()->isValid() == false)) { lEvalVector.push_back(i); Beagle_LogDebugM( ioContext.getSystem().getLogger(), "Added " << uint2ordinal(i+1) << " individual for evaluation." ); } } std::random_shuffle(lEvalVector.begin(), lEvalVector.end(), ioContext.getSystem().getRandomizer()); Beagle_LogDebugM( ioContext.getSystem().getLogger(), "There are " << lEvalVector.size() << " individuals to be evaluated." ); History::Handle lHistory = castHandleT<History>(ioContext.getSystem().haveComponent("History")); while ( !lEvalVector.empty() ) { // Put individuals and context into bags. Individual::Bag lIndividuals; Context::Bag lContexts; lIndividuals.resize( mIndisPerGroup ); lContexts.resize( mIndisPerGroup ); unsigned int lIndiCounter =0; for (unsigned int i=0; i<mIndisPerGroup; i++) { // Set individual lIndividuals[i] = ioDeme[lEvalVector.back()]; lIndiCounter++; // Set context Context::Alloc::Handle lContextAlloc = castHandleT<Context::Alloc>(ioContext.getSystem().getFactory().getConceptAllocator("Context")); Context::Handle lContext = castHandleT<Context>(lContextAlloc->clone(ioContext)); lContext->setIndividualIndex( lEvalVector.back() ); lContext->setIndividualHandle( ioDeme[lEvalVector.back()] ); lContexts[i] = lContext; // Remove this index from the evaluation vector lEvalVector.pop_back(); if(lEvalVector.empty()) { lIndividuals.resize( lIndiCounter ); lContexts.resize( lIndiCounter ); break; } } // Evaluate individuals std::ostringstream lOSS; lOSS << "Evaluating the fitness of the "; for(unsigned int i=0; i<lIndiCounter; i++) { // Add to message if (i==lIndiCounter-1) lOSS << " and "; lOSS << uint2ordinal(lContexts[i]->getIndividualIndex()+1); if (i<lIndiCounter-2) lOSS << ", "; } lOSS << " individuals"; Beagle_LogVerboseM( ioContext.getSystem().getLogger(), lOSS.str() ); Fitness::Bag::Handle lFitnessBag = evaluateIndividuals(lIndividuals, lContexts); // Assign fitnesses for (unsigned int i=0; i<lIndiCounter; i++) { Beagle_LogDebugM( ioContext.getSystem().getLogger(), "Considering fitness of the " << uint2ordinal(lContexts[i]->getIndividualIndex()+1) << " individual" ); Beagle_AssertM( i < lFitnessBag->size() ); Fitness::Handle lFitness = lFitnessBag->at(i); Beagle_NonNullPointerAssertM( lFitness ); lIndividuals[i]->setFitness( lFitness ); lIndividuals[i]->getFitness()->setValid(); if(lHistory != NULL) { lHistory->allocateID(*lIndividuals[i]); lHistory->trace(ioContext, std::vector<HistoryID>(), lIndividuals[i], getName(), "evaluation"); } Beagle_LogVerboseM( ioContext.getSystem().getLogger(), *lIndividuals[i]->getFitness() ); } // Update stats updateStats(lIndividuals.size(),ioContext); } updateHallOfFameWithDeme(ioDeme,ioContext); Beagle_StackTraceEndM(); }
/*! * \brief Apply the initialization operation on the deme. * \param ioDeme Current deme of individuals to initialize. * \param ioContext Context of the evolution. */ void InitializationOp::operate(Deme& ioDeme, Context& ioContext) { Beagle_StackTraceBeginM(); #ifndef BEAGLE_NDEBUG if(ioContext.getVivariumHandle()!=NULL) { Beagle_AssertM(mPopSize->size() == ioContext.getVivarium().size()); } #endif // BEAGLE_NDEBUG Beagle_LogTraceM( ioContext.getSystem().getLogger(), std::string("Initializing the ")+ uint2ordinal(ioContext.getDemeIndex()+1)+" deme" ); if(!ioDeme.empty()) { Beagle_LogBasicM( ioContext.getSystem().getLogger(), std::string("Warning! Applying '")+getName()+"' will overwrite the "+ uint2str(ioDeme.size())+" individual(s) currently in the deme with newly initialized "+ "individuals. If this is not what you desire consider using OversizeOp instead." ); } Beagle_LogTraceM( ioContext.getSystem().getLogger(), std::string("Resizing the deme from ")+ uint2str(ioDeme.size())+" to "+ uint2str((*mPopSize)[ioContext.getDemeIndex()])+" individuals" ); const Factory& lFactory = ioContext.getSystem().getFactory(); Individual::Alloc::Handle lIndividualAlloc = castHandleT<Individual::Alloc>(lFactory.getConceptAllocator("Individual")); ioDeme.clear(); const unsigned int lDemeSize = (*mPopSize)[ioContext.getDemeIndex()]; for(unsigned int i=0; i<lDemeSize; ++i) { ioDeme.push_back(lIndividualAlloc->allocate()); } unsigned int lSeededIndividuals = 0; if(mSeedsFile->getWrappedValue().empty() == false) { Beagle_LogInfoM( ioContext.getSystem().getLogger(), std::string("Reading seeds file '")+mSeedsFile->getWrappedValue()+ std::string("' to initialize the ")+uint2ordinal(ioContext.getDemeIndex()+1)+ std::string(" deme") ); lSeededIndividuals = readSeeds(mSeedsFile->getWrappedValue(), ioDeme, ioContext); Beagle_LogDetailedM( ioContext.getSystem().getLogger(), uint2str(lSeededIndividuals)+std::string(" individuals read to seed the deme") ); } History::Handle lHistory = castHandleT<History>(ioContext.getSystem().haveComponent("History")); Individual::Handle lOldIndividualHandle = ioContext.getIndividualHandle(); unsigned int lOldIndividualIndex = ioContext.getIndividualIndex(); for(unsigned int i=lSeededIndividuals; i<ioDeme.size(); ++i) { Beagle_LogVerboseM( ioContext.getSystem().getLogger(), std::string("Initializing the ")+uint2ordinal(i+1)+" individual" ); ioContext.setIndividualHandle(ioDeme[i]); ioContext.setIndividualIndex(i); initIndividual(*ioDeme[i], ioContext); if(ioDeme[i]->getFitness() != NULL) { ioDeme[i]->getFitness()->setInvalid(); } if(lHistory != NULL) { lHistory->incrementHistoryVar(*ioDeme[i]); lHistory->trace(ioContext, std::vector<HistoryID>(), ioDeme[i], getName(), "initialization"); } } ioContext.setIndividualIndex(lOldIndividualIndex); ioContext.setIndividualHandle(lOldIndividualHandle); Beagle_StackTraceEndM(); }
/*! * \brief Generate children from the breeder tree. * \param ioDeme Deme to generate children from. * \param ioContext Evolutionary context. * \param lNbChildren Number of children to generate. * \param inN Dimensionality of the problem. * \param ioCMAValues CMA values to use to generate new individual. * \param inSelectionWeights Selection weights used to generate children. */ void CMA::MuWCommaLambdaCMAFltVecOp::generateChildren(Deme& ioDeme, Context& ioContext, unsigned int inNbChildren, unsigned int inN, CMAValues& ioCMAValues, const Vector& inSelectionWeights) const { Beagle_StackTraceBeginM(); // Check parameters and log some information Beagle_NonNullPointerAssertM(mElitismKeepSize); Beagle_ValidateParameterM(mLMRatio->getWrappedValue() >= 1.0, mLMRatioName, "The LM ratio must be higher or equal to 1.0."); Beagle_ValidateParameterM(mElitismKeepSize->getWrappedValue() <= ioDeme.size(), "ec.elite.keepsize", "The elistism keepsize must be less than the deme size!"); Beagle_LogTraceM( ioContext.getSystem().getLogger(), std::string("Using CMA-ES (mu_w,lambda) replacement strategy to process the ")+ uint2ordinal(ioContext.getDemeIndex()+1)+" deme" ); Beagle_LogTraceM(ioContext.getSystem().getLogger(), (*this)); const Factory& lFactory = ioContext.getSystem().getFactory(); // Create weighted mean individual. std::sort(ioDeme.begin(), ioDeme.end(), IsMorePointerPredicate()); Individual::Alloc::Handle lIndividualAlloc = castHandleT<Individual::Alloc>(lFactory.getConceptAllocator("Individual")); Individual::Handle lMeanInd = castHandleT<Individual>(lIndividualAlloc->allocate()); Genotype::Alloc::Handle lGenotypeAlloc = castHandleT<Genotype::Alloc>(lFactory.getConceptAllocator("Genotype")); FltVec::FloatVector::Handle lMeanFloatVec = castHandleT<FltVec::FloatVector>(lGenotypeAlloc->allocate()); lMeanFloatVec->resize(inN); lMeanInd->push_back(lMeanFloatVec); for(unsigned int i=0; i<inN; ++i) (*lMeanFloatVec)[i] = 0.0; if(ioDeme.size()==1) { Beagle_AssertM(ioDeme[0]->size() == 1); FltVec::FloatVector::Handle lInd = castHandleT<FltVec::FloatVector>((*ioDeme[0])[0]); (*lMeanFloatVec) = *lInd; } else { for(unsigned int i=0; i<ioDeme.size(); ++i) { Beagle_AssertM(ioDeme[i]->size()==1); FltVec::FloatVector::Handle lVecI = castHandleT<FltVec::FloatVector>((*ioDeme[i])[0]); Beagle_AssertM(lVecI->size()==inN); for(unsigned int j=0; j<inN; ++j) (*lMeanFloatVec)[j] += (inSelectionWeights[i] * (*lVecI)[j]); } } ioCMAValues.mXmean.resize(inN); for(unsigned int i=0; i<inN; ++i) ioCMAValues.mXmean[i] = (*lMeanFloatVec)[i]; // Generate lambda children with breeder tree, first build breeder roulette RouletteT<unsigned int> lRoulette; buildRoulette(lRoulette, ioContext); // Keep best individuals if elitism is used const unsigned int lElitismKS=mElitismKeepSize->getWrappedValue(); if(lElitismKS > 0) { Individual::Bag lBestInd; History::Handle lHistory = castHandleT<History>(ioContext.getSystem().haveComponent("History")); std::make_heap(ioDeme.begin(), ioDeme.end(), IsLessPointerPredicate()); for(unsigned int i=0; i<lElitismKS; ++i) { if(lHistory != NULL) { HistoryID::Handle lHID = castHandleT<HistoryID>(ioDeme[0]->getMember("HistoryID")); std::vector<HistoryID> lParent; if(lHID != NULL) lParent.push_back(*lHID); lHistory->allocateNewID(*ioDeme[0]); lHistory->trace(ioContext, lParent, ioDeme[0], getName(), "elitism"); } lBestInd.push_back(ioDeme[0]); std::pop_heap(ioDeme.begin(), ioDeme.end(), IsLessPointerPredicate()); ioDeme.pop_back(); } ioDeme.clear(); ioDeme.insert(ioDeme.end(), lBestInd.begin(), lBestInd.end()); } else ioDeme.clear(); // Generate the children Individual::Bag lBagWithMeanInd; lBagWithMeanInd.push_back(lMeanInd); for(unsigned int i=0; i<inNbChildren; ++i) { unsigned int lIndexBreeder = lRoulette.select(ioContext.getSystem().getRandomizer()); BreederNode::Handle lSelectedBreeder=getRootNode(); for(unsigned int j=0; j<lIndexBreeder; ++j) lSelectedBreeder=lSelectedBreeder->getNextSibling(); Beagle_NonNullPointerAssertM(lSelectedBreeder); Beagle_NonNullPointerAssertM(lSelectedBreeder->getBreederOp()); Individual::Handle lBredIndiv = lSelectedBreeder->getBreederOp()->breed(lBagWithMeanInd, lSelectedBreeder->getFirstChild(), ioContext); Beagle_NonNullPointerAssertM(lBredIndiv); ioDeme.push_back(lBredIndiv); } Beagle_StackTraceEndM(); }
/*! * \brief Apply the crossover operation on the deme. * \param ioDeme Current deme of individuals to mate. * \param ioContext Context of the evolution. */ void CrossoverOp::operate(Deme& ioDeme, Context& ioContext) { Beagle_StackTraceBeginM(); Beagle_ValidateParameterM(mMatingProba->getWrappedValue()>=0.0, mMatingProbaName, "<0"); Beagle_LogTraceM( ioContext.getSystem().getLogger(), std::string("Mating individuals of the ")+ uint2ordinal(ioContext.getDemeIndex()+1)+" deme" ); Beagle_LogVerboseM( ioContext.getSystem().getLogger(), std::string("Mating individuals with probability ")+ dbl2str(mMatingProba->getWrappedValue()) ); History::Handle lHistory = castHandleT<History>(ioContext.getSystem().haveComponent("History")); Individual::Handle lOldIndividualHandle = ioContext.getIndividualHandle(); unsigned int lOldIndividualIndex = ioContext.getIndividualIndex(); std::vector<unsigned int> lMateVector; for(unsigned int i=0; i<ioDeme.size(); i++) { if(ioContext.getSystem().getRandomizer().rollUniform() <= mMatingProba->getWrappedValue()) { lMateVector.push_back(i); } } std::random_shuffle(lMateVector.begin(), lMateVector.end(), ioContext.getSystem().getRandomizer()); if((lMateVector.size() % 2) != 0) lMateVector.pop_back(); int j = 0; int lSize = lMateVector.size(); #if defined(BEAGLE_USE_OMP_NR) || defined(BEAGLE_USE_OMP_R) static OpenMP::Handle lOpenMP = castHandleT<OpenMP>(ioContext.getSystem().getComponent("OpenMP")); const Factory& lFactory = ioContext.getSystem().getFactory(); const std::string& lContextName = lFactory.getConceptTypeName("Context"); Context::Alloc::Handle lContextAlloc = castHandleT<Context::Alloc>(lFactory.getAllocator(lContextName)); Context::Bag lContexts(lOpenMP->getMaxNumThreads()); Context::Bag lContexts2(lOpenMP->getMaxNumThreads()); for(unsigned int i = 0; i < lOpenMP->getMaxNumThreads(); ++i) { lContexts[i] = castHandleT<Context>(lContextAlloc->clone(ioContext)); lContexts2[i] = castHandleT<Context>(lContextAlloc->clone(ioContext)); } #if defined(BEAGLE_USE_OMP_NR) #pragma omp parallel for shared(lSize, lMateVector, lHistory, lContexts, lContexts2) private(j) schedule(dynamic) #elif defined(BEAGLE_USE_OMP_R) const int lChunkSize = std::max((int)(lSize / lOpenMP->getMaxNumThreads()), 1); #pragma omp parallel for shared(lSize, lMateVector, lHistory, lContexts, lContexts2) private(j) schedule(static, lChunkSize) #endif #else Context::Alloc::Handle lContextAlloc = castHandleT<Context::Alloc>(ioContext.getSystem().getFactory().getConceptAllocator("Context")); Context::Handle lContext2 = castHandleT<Context>(lContextAlloc->clone(ioContext)); #endif for(j=0; j<lSize; j+=2) { unsigned int lFirstMate = lMateVector[j]; unsigned int lSecondMate = lMateVector[j+1]; #if defined(BEAGLE_USE_OMP_NR) || defined(BEAGLE_USE_OMP_R) lContexts[lOpenMP->getThreadNum()]->setIndividualIndex(lFirstMate); lContexts[lOpenMP->getThreadNum()]->setIndividualHandle(ioDeme[lFirstMate]); lContexts2[lOpenMP->getThreadNum()]->setIndividualIndex(lSecondMate); lContexts2[lOpenMP->getThreadNum()]->setIndividualHandle(ioDeme[lSecondMate]); #else ioContext.setIndividualIndex(lFirstMate); ioContext.setIndividualHandle(ioDeme[lFirstMate]); lContext2->setIndividualIndex(lSecondMate); lContext2->setIndividualHandle(ioDeme[lSecondMate]); #endif Beagle_LogVerboseM( ioContext.getSystem().getLogger(), std::string("Mating the ")+uint2ordinal(lFirstMate+1)+ std::string(" individual with the ")+uint2ordinal(lSecondMate+1)+" individual" ); std::vector<HistoryID> lParents; if(lHistory != NULL) { #pragma omp critical (Beagle_History) { HistoryID::Handle lHID1 = castHandleT<HistoryID>(ioDeme[lFirstMate]->getMember("HistoryID")); if(lHID1 != NULL) lParents.push_back(*lHID1); HistoryID::Handle lHID2 = castHandleT<HistoryID>(ioDeme[lSecondMate]->getMember("HistoryID")); if(lHID2 != NULL) lParents.push_back(*lHID2); } } #if defined(BEAGLE_USE_OMP_NR) || defined(BEAGLE_USE_OMP_R) bool lMated = mate(*ioDeme[lFirstMate], *(lContexts[lOpenMP->getThreadNum()]), *ioDeme[lSecondMate], *(lContexts2[lOpenMP->getThreadNum()])); #else bool lMated = mate(*ioDeme[lFirstMate], ioContext, *ioDeme[lSecondMate], *lContext2); #endif if(lMated) { if(ioDeme[lFirstMate]->getFitness() != NULL) { ioDeme[lFirstMate]->getFitness()->setInvalid(); } if(ioDeme[lSecondMate]->getFitness() != NULL) { ioDeme[lSecondMate]->getFitness()->setInvalid(); } if(lHistory != NULL) { #pragma omp critical (Beagle_History) { lHistory->incrementHistoryVar(*ioDeme[lFirstMate]); #if defined(BEAGLE_USE_OMP_R) || defined(BEAGLE_USE_OMP_NR) lHistory->trace(*lContexts[lOpenMP->getThreadNum()], lParents, ioDeme[lFirstMate], getName(), "crossover"); #else lHistory->trace(ioContext, lParents, ioDeme[lFirstMate], getName(), "crossover"); #endif lHistory->incrementHistoryVar(*ioDeme[lSecondMate]); #if defined(BEAGLE_USE_OMP_R) || defined(BEAGLE_USE_OMP_NR) lHistory->trace(*lContexts[lOpenMP->getThreadNum()], lParents, ioDeme[lSecondMate], getName(), "crossover"); #else lHistory->trace(ioContext, lParents, ioDeme[lSecondMate], getName(), "crossover"); #endif } } } } ioContext.setIndividualIndex(lOldIndividualIndex); ioContext.setIndividualHandle(lOldIndividualHandle); Beagle_StackTraceEndM(); }
/*! * \brief Apply the recombination operation on a breeding pool, returning a recombined individual. * \param inBreedingPool Breeding pool to use for the recombination operation. * \param inChild Node handle associated to child node in the breeder tree. * \param ioContext Evolutionary context of the recombination operation. * \return Recombined individual. */ Individual::Handle RecombinationOp::breed(Individual::Bag& inBreedingPool, BreederNode::Handle inChild, Context& ioContext) { Beagle_StackTraceBeginM(); // Generate parents for recombination. Individual::Bag::Handle lParents = new Individual::Bag; if(inChild == NULL) { const unsigned int lNbGenerated = (mNumberRecomb->getWrappedValue()==0) ? inBreedingPool.size() : minOf<unsigned int>(inBreedingPool.size(), mNumberRecomb->getWrappedValue()); if(lNbGenerated == inBreedingPool.size()) (*lParents) = inBreedingPool; else { std::vector<unsigned int> lIndices(inBreedingPool.size()); for(unsigned int i=0; i<lIndices.size(); ++i) lIndices[i] = i; std::random_shuffle(lIndices.begin(), lIndices.end(), ioContext.getSystem().getRandomizer()); for(unsigned int i=0; i<lNbGenerated; ++i) { lParents->push_back(inBreedingPool[lIndices[i]]); } } } else { Beagle_NonNullPointerAssertM(inChild->getBreederOp()); const unsigned int lNbGenerated = (mNumberRecomb->getWrappedValue()==0) ? inBreedingPool.size() : minOf<unsigned int>(inBreedingPool.size(), mNumberRecomb->getWrappedValue()); for(unsigned int i=0; i<lNbGenerated; ++i) { Individual::Handle lIndiv = inChild->getBreederOp()->breed(inBreedingPool, inChild->getFirstChild(), ioContext); lParents->push_back(lIndiv); } } // Log parents selected for recombination. Beagle_LogVerboseM( ioContext.getSystem().getLogger(), std::string("Recombining ")+uint2str(lParents->size())+std::string(" individuals together") ); // Do recombination operation on parent and get the resulting child. Individual::Handle lChildIndiv = recombine(*lParents, ioContext); if(lChildIndiv->getFitness() != NULL) { lChildIndiv->getFitness()->setInvalid(); } // Log information to history, if it is used. History::Handle lHistory = castHandleT<History>(ioContext.getSystem().haveComponent("History")); if(lHistory != NULL) { std::vector<HistoryID> lParentNames; for(unsigned int i=0; i<lParents->size(); ++i) { HistoryID::Handle lHID = castHandleT<HistoryID>(lParents->at(i)->getMember("HistoryID")); if(lHID != NULL) lParentNames.push_back(*lHID); } lHistory->incrementHistoryVar(*lChildIndiv); lHistory->trace(ioContext, lParentNames, lChildIndiv, getName(), "recombination"); } return lChildIndiv; Beagle_StackTraceEndM(); }
/*! * \brief Apply the recombination operation on the deme. * \param ioDeme Current deme of individuals to recombine. * \param ioContext Context of the evolution. */ void RecombinationOp::operate(Deme& ioDeme, Context& ioContext) { Beagle_StackTraceBeginM(); Beagle_ValidateParameterM(mRecombProba->getWrappedValue()>=0.0, mRecombProbaName, "<0"); Beagle_LogTraceM( ioContext.getSystem().getLogger(), std::string("Recombining individuals of the ")+ uint2ordinal(ioContext.getDemeIndex()+1)+" deme" ); Beagle_LogVerboseM( ioContext.getSystem().getLogger(), std::string("Recombining individuals with probability ")+ dbl2str(mRecombProba->getWrappedValue()) ); History::Handle lHistory = castHandleT<History>(ioContext.getSystem().haveComponent("History")); Individual::Bag lRecombinedIndiv(ioDeme.size()); for(unsigned int i=0; i<lRecombinedIndiv.size(); ++i) { if(ioContext.getSystem().getRandomizer().rollUniform() <= mRecombProba->getWrappedValue()) { Individual::Bag::Handle lParents = new Individual::Bag; const unsigned int lNbGenerated = (mNumberRecomb->getWrappedValue()==0) ? ioDeme.size() : minOf<unsigned int>(ioDeme.size(), mNumberRecomb->getWrappedValue()); if(lNbGenerated == ioDeme.size()) (*lParents) = ioDeme; else { std::vector<unsigned int> lIndices(ioDeme.size()); for(unsigned int j=0; j<lIndices.size(); ++j) lIndices[j] = j; std::random_shuffle(lIndices.begin(), lIndices.end(), ioContext.getSystem().getRandomizer()); for(unsigned int j=0; j<lNbGenerated; ++j) { lParents->push_back(ioDeme[lIndices[j]]); } } lRecombinedIndiv[i] = recombine(*lParents, ioContext); if(lRecombinedIndiv[i]->getFitness() != NULL) { lRecombinedIndiv[i]->getFitness()->setInvalid(); } // Log and update history. Beagle_LogVerboseM( ioContext.getSystem().getLogger(), std::string("The ")+uint2ordinal(i+1)+ std::string(" individual as been replaced by recombination") ); if(lHistory != NULL) { std::vector<HistoryID> lParentNames; for(unsigned int j=0; j<lParents->size(); ++j) { HistoryID::Handle lHID = castHandleT<HistoryID>(lParents->at(j)->getMember("HistoryID")); if(lHID != NULL) lParentNames.push_back(*lHID); } lHistory->incrementHistoryVar(*lRecombinedIndiv[i]); lHistory->trace(ioContext, lParentNames, lRecombinedIndiv[i], getName(), "recombination"); } } } for(unsigned int i=0; i<ioDeme.size(); ++i) { if(lRecombinedIndiv[i] != NULL) ioDeme[i] = lRecombinedIndiv[i]; } Beagle_StackTraceEndM(); }