/*! * \brief Recombine individuals by weighted mean to generate a new individual. * \param inIndivPool Parents being recombined. * \param ioContext Evolutionary context. * \return Children generated by recombination. */ Individual::Handle SAES::RecombinationWeightedOp::recombine(Individual::Bag& inIndivPool, Context& ioContext) { Beagle_StackTraceBeginM(); // Compute recombination weights. std::vector<double> lWeights(inIndivPool.size()); for(unsigned int i=0; i<lWeights.size(); ++i) { lWeights[i] = std::log(double(lWeights.size()+1)); lWeights[i] -= std::log(double(i+1)); } // Recombine parents to generate new individual. const Factory& lFactory = ioContext.getSystem().getFactory(); Individual::Alloc::Handle lIndivAlloc = castHandleT<Individual::Alloc>(lFactory.getConceptAllocator("Individual")); Genotype::Alloc::Handle lGenotypeAlloc = castHandleT<Genotype::Alloc>(lFactory.getConceptAllocator("Genotype")); Individual::Handle lChildIndiv = castHandleT<Individual>(lIndivAlloc->allocate()); std::vector< std::vector<double> > lCountGenoSum; for(unsigned int i=0; i<inIndivPool.size(); ++i) { const unsigned int lPoolISize = inIndivPool[i]->size(); const unsigned int lChildSize = lChildIndiv->size(); if(lPoolISize > lChildSize) { lCountGenoSum.resize(lPoolISize); lChildIndiv->resize(lPoolISize); for(unsigned int j=lChildSize; j<lPoolISize; ++j) { (*lChildIndiv)[j] = castHandleT<Genotype>(lGenotypeAlloc->allocate()); } } for(unsigned int j=0; j<lPoolISize; ++j) { SAES::PairVector::Handle lChildGenoJ = castHandleT<SAES::PairVector>((*lChildIndiv)[j]); SAES::PairVector::Handle lPoolIGenoJ = castHandleT<SAES::PairVector>((*inIndivPool[i])[j]); const unsigned int lPoolIGenoJSize = lPoolIGenoJ->size(); if(lPoolIGenoJSize > lChildGenoJ->size()) { lChildGenoJ->resize(lPoolIGenoJSize,0.0); lCountGenoSum[j].resize(lPoolIGenoJSize,0); } for(unsigned int k=0; k<lPoolIGenoJSize; ++k) { (*lChildGenoJ)[k].mValue += (lWeights[i] * (*lPoolIGenoJ)[k].mValue); (*lChildGenoJ)[k].mStrategy += (lWeights[i] * (*lPoolIGenoJ)[k].mStrategy); lCountGenoSum[j][k] += lWeights[i]; } } } for(unsigned int i=0; i<lChildIndiv->size(); ++i) { SAES::PairVector::Handle lChildGenoI = castHandleT<SAES::PairVector>((*lChildIndiv)[i]); for(unsigned int j=0; j<lChildGenoI->size(); ++j) { (*lChildGenoI)[j].mValue /= lCountGenoSum[i][j]; (*lChildGenoI)[j].mStrategy /= lCountGenoSum[i][j]; } } Beagle_LogDebugM(ioContext.getSystem().getLogger(), *lChildIndiv); return lChildIndiv; Beagle_StackTraceEndM(); }
/*! * \brief Copy individual using the system. * \param inOriginal Individual to copy into current. * \param ioSystem Evolutionary system. */ void Individual::copy(const Individual& inOriginal, System& ioSystem) { Beagle_StackTraceBeginM(); const Factory& lFactory = ioSystem.getFactory(); // Copy members mMemberMap.clear(); for(MemberMap::const_iterator lIterMap=inOriginal.mMemberMap.begin(); lIterMap!=inOriginal.mMemberMap.end(); ++lIterMap) { Member::Handle lOrigMember = castHandleT<Member>(lIterMap->second); const std::string& lMemberType = lOrigMember->getType(); Member::Alloc::Handle lMemberAlloc = castHandleT<Member::Alloc>(lFactory.getAllocator(lMemberType)); Member::Handle lMember = castHandleT<Member>(lMemberAlloc->allocate()); lMember->copy(*lOrigMember, ioSystem); mMemberMap[lIterMap->first] = lMember; } // Copy fitness if(inOriginal.getFitness() == NULL) { mFitness = NULL; } else { const std::string& lFitnessType = inOriginal.getFitness()->getType(); Fitness::Alloc::Handle lFitnessAlloc = castHandleT<Fitness::Alloc>(lFactory.getAllocator(lFitnessType)); mFitness = castHandleT<Fitness>(lFitnessAlloc->allocate()); mFitness->copy(*inOriginal.getFitness(), ioSystem); } // Copy genotypes resize(inOriginal.size()); for(unsigned int i=0; i<inOriginal.size(); ++i) { const std::string& lGenotypeType = inOriginal[i]->getType(); Genotype::Alloc::Handle lGenotypeAlloc = castHandleT<Genotype::Alloc>(lFactory.getAllocator(lGenotypeType)); (*this)[i] = castHandleT<Genotype>(lGenotypeAlloc->allocate()); (*this)[i]->copy(*inOriginal[i], ioSystem); } Beagle_StackTraceEndM(); }
/*! * \brief Read genotypes of an individual from an XML node. * \param inIter XML iterator to read the individual's genotypes from. * \param ioContext Evolutionary context. * \throw Beagle::IOException If the format is not respected. */ void Individual::readGenotypes(PACC::XML::ConstIterator inIter, Context& ioContext) { Beagle_StackTraceBeginM(); const Factory& lFactory = ioContext.getSystem().getFactory(); unsigned int lPrevGenoIndex = ioContext.getGenotypeIndex(); Genotype::Handle lPrevGenoHandle = ioContext.getGenotypeHandle(); clear(); for(PACC::XML::ConstIterator lIter=inIter; lIter; ++lIter) { if((lIter->getType() != PACC::XML::eData) || (lIter->getValue() != "Genotype")) continue; const std::string& lGenotypeType = lIter->getAttribute("type"); Genotype::Alloc::Handle lGenotypeAlloc = NULL; if(lGenotypeType.empty()) { lGenotypeAlloc = castHandleT<Genotype::Alloc>(lFactory.getConceptAllocator("Genotype")); if(lGenotypeAlloc == NULL) { std::ostringstream lOSS; lOSS << "Genotype object can't be read, "; lOSS << "it appears that its type is not given and that there is not "; lOSS << "valid concept allocator associated to it!"; throw Beagle_IOExceptionNodeM(*lIter, lOSS.str()); } } else { lGenotypeAlloc = castHandleT<Genotype::Alloc>(lFactory.getAllocator(lGenotypeType)); if(lGenotypeAlloc == NULL) { std::ostringstream lOSS; lOSS << "Type '" << lGenotypeType << "' associated to genotype object "; lOSS << "is not valid!"; throw Beagle_IOExceptionNodeM(*lIter, lOSS.str()); } } Genotype::Handle lGenotype = castHandleT<Genotype>(lGenotypeAlloc->allocate()); ioContext.setGenotypeHandle(lGenotype); ioContext.setGenotypeIndex(size()); push_back(lGenotype); lGenotype->readWithContext(lIter, ioContext); } ioContext.setGenotypeHandle(lPrevGenoHandle); ioContext.setGenotypeIndex(lPrevGenoIndex); 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 Recombine individuals by averaging to generate a new individual. * \param inIndivPool Parents being recombined. * \param ioContext Evolutionary context. * \return Children generated by recombination. */ Individual::Handle Beagle::GA::RecombinationESVecOp::recombine(Individual::Bag& inIndivPool, Context& ioContext) { Beagle_StackTraceBeginM(); // Recombine parents to generate new individual. const Factory& lFactory = ioContext.getSystem().getFactory(); Individual::Alloc::Handle lIndivAlloc = castHandleT<Individual::Alloc>(lFactory.getConceptAllocator("Individual")); Genotype::Alloc::Handle lGenotypeAlloc = castHandleT<Genotype::Alloc>(lFactory.getConceptAllocator("Genotype")); Individual::Handle lChildIndiv = castHandleT<Individual>(lIndivAlloc->allocate()); std::vector< std::vector<unsigned int> > lCountGenoSum; for(unsigned int i=0; i<inIndivPool.size(); ++i) { const unsigned int lPoolISize = inIndivPool[i]->size(); const unsigned int lChildSize = lChildIndiv->size(); if(lPoolISize > lChildSize) { lCountGenoSum.resize(lPoolISize); lChildIndiv->resize(lPoolISize); for(unsigned int j=lChildSize; j<lPoolISize; ++j) { (*lChildIndiv)[j] = castHandleT<Genotype>(lGenotypeAlloc->allocate()); } } for(unsigned int j=0; j<lPoolISize; ++j) { GA::ESVector::Handle lChildGenoJ = castHandleT<GA::ESVector>((*lChildIndiv)[j]); GA::ESVector::Handle lPoolIGenoJ = castHandleT<GA::ESVector>((*inIndivPool[i])[j]); const unsigned int lPoolIGenoJSize = lPoolIGenoJ->size(); if(lPoolIGenoJSize > lChildGenoJ->size()) { lChildGenoJ->resize(lPoolIGenoJSize,0.0); lCountGenoSum[j].resize(lPoolIGenoJSize,0); } for(unsigned int k=0; k<lPoolIGenoJSize; ++k) { (*lChildGenoJ)[k].mValue += (*lPoolIGenoJ)[k].mValue; (*lChildGenoJ)[k].mStrategy += (*lPoolIGenoJ)[k].mStrategy; ++lCountGenoSum[j][k]; } } } for(unsigned int i=0; i<lChildIndiv->size(); ++i) { GA::ESVector::Handle lChildGenoI = castHandleT<GA::ESVector>((*lChildIndiv)[i]); for(unsigned int j=0; j<lChildGenoI->size(); ++j) { (*lChildGenoI)[j].mValue /= double(lCountGenoSum[i][j]); (*lChildGenoI)[j].mStrategy /= double(lCountGenoSum[i][j]); } } Beagle_LogDebugM( ioContext.getSystem().getLogger(), "crossover", "Beagle::GA::RecombinationESVecOp", "Individual generated by recombination" ); Beagle_LogObjectDebugM( ioContext.getSystem().getLogger(), "crossover", "Beagle::GA::RecombinationESVecOp", *lChildIndiv ); return lChildIndiv; Beagle_StackTraceEndM("Individual::Handle Beagle::GA::RecombinationESVecOp::recombine(Individual::Bag& inIndivPool,Context& ioContext)"); }
/*! * \brief Initialize the trees of an individual. * \param outIndividual Individual to initialize. * \param ioContext Evolution context. * \throw Beagle::RunTimeException If the min/max depths are incorrectly set. */ void GP::InitializationOp::initIndividual(Beagle::Individual& outIndividual, Beagle::Context& ioContext) { Beagle_StackTraceBeginM(); #ifndef BEAGLE_NDEBUG if (mMinTreeDepth==NULL || mMaxTreeDepth==NULL) throw Beagle_RunTimeExceptionM(std::string("GP::InitializationOp has not been initialized."). append(" Consider the GP::InitializationOp::registerParams() method.")); if(*mMinTreeDepth > *mMaxTreeDepth) { std::string lMessage = "GP::InitializationOp::initIndividual: Minimum tree depth is superior "; lMessage += "to the maximum tree depth. Could not initialize the individuals!"; throw Beagle::ValidationException(lMessage); } #endif // BEAGLE_NDEBUG Beagle_ValidateParameterM(mMinTreeDepth->getWrappedValue()>0,"gp.init.mindepth",">0"); GP::Individual& lIndividual = castObjectT<GP::Individual&>(outIndividual); GP::Context& lContext = castObjectT<GP::Context&>(ioContext); GP::PrimitiveSuperSet::Handle lSuperSet = castHandleT<GP::PrimitiveSuperSet>(ioContext.getSystem().getComponent("GP-PrimitiveSuperSet")); if(lSuperSet == NULL) { throw Beagle_RunTimeExceptionM("There should be a GP::PrimitiveSuperSet component in the system"); } const unsigned int lPrimitiveSuperSetSize = lSuperSet->size(); const Factory& lFactory = ioContext.getSystem().getFactory(); #ifndef BEAGLE_NDEBUG if(lPrimitiveSuperSetSize == 0) throw Beagle_RunTimeExceptionM(std::string("GP::InitializationOp::initIndividual(): There "). append(" are no PrimitiveSets in the PrimitiveSuperSet. There needs to be at least one"). append(" PrimitiveSet. See the examples that are included with Beagle to learn how"). append(" to create a PrimitiveSet, add Primitives to it, and then construct a System based"). append(" on the PrimitiveSet.")); #endif // BEAGLE_NDEBUG // Choose randomly the number of individuals in tree const unsigned int lMaxDepth = mMaxTreeDepth->getWrappedValue(); const unsigned int lMinDepth = mMinTreeDepth->getWrappedValue(); const unsigned int lMaxNbTrees = mMaxNumberTrees->getWrappedValue(); const unsigned int lMinNbTrees = mMinNumberTrees->getWrappedValue(); Beagle_AssertM(lMaxNbTrees >= lMinNbTrees); const unsigned int lNbTrees = ioContext.getSystem().getRandomizer().rollInteger(lMinNbTrees,lMaxNbTrees); Genotype::Alloc::Handle lGenotypeAlloc = castHandleT<Genotype::Alloc>(lFactory.getConceptAllocator("Genotype")); lIndividual.clear(); for(unsigned int i=0; i<lNbTrees; ++i) { lIndividual.push_back(castHandleT<Genotype>(lGenotypeAlloc->allocate())); } GP::Tree::Handle lOldTreeHandle = lContext.getGenotypeHandle(); unsigned int lOldTreeIndex = lContext.getGenotypeIndex(); for(unsigned int i=0; i<lIndividual.size(); ++i) { if(i<lPrimitiveSuperSetSize) lIndividual[i]->setPrimitiveSetIndex(i); else lIndividual[i]->setPrimitiveSetIndex(lPrimitiveSuperSetSize-1); const unsigned int lMaxArgs = (i<mMaxTreeArgs->size()) ? (*mMaxTreeArgs)[i] : mMaxTreeArgs->back(); const unsigned int lMinArgs = (i<mMinTreeArgs->size()) ? (*mMinTreeArgs)[i] : mMinTreeArgs->back(); Beagle_AssertM(lMaxArgs >= lMinArgs); const unsigned int lNbArgs = ioContext.getSystem().getRandomizer().rollInteger(lMinArgs,lMaxArgs); lIndividual[i]->setNumberArguments(lNbArgs); } for(unsigned int i=0; i<lIndividual.size(); ++i) { lContext.setGenotypeHandle(lIndividual[i]); lContext.setGenotypeIndex(i); const unsigned int lTreeDepth = lContext.getSystem().getRandomizer().rollInteger(lMinDepth,lMaxDepth); lContext.emptyCallStack(); lIndividual[i]->clear(); initTree(*lIndividual[i], lMinDepth, lTreeDepth, lContext); } Beagle_LogDebugM( ioContext.getSystem().getLogger(), "initialization", "Beagle::GP::InitializationOp", std::string("Initialized individual:") ); Beagle_LogObjectDebugM( ioContext.getSystem().getLogger(), "initialization", "Beagle::GP::InitializationOp", lIndividual ); lContext.setGenotypeIndex(lOldTreeIndex); lContext.setGenotypeHandle(lOldTreeHandle); Beagle_StackTraceEndM(); }