/*! * \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 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 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(); }