void LogIndividualDataOp::operate(Deme& ioDeme, Context& ioContext) { Beagle_StackTraceBeginM(); if(mNumberIndividualPerDem->getWrappedValue() <= 0) { return; } // Temporary buffer of individuals. Individual::Bag lTempPop; if(ioContext.getGeneration() != mGenerationCalculated) { mGenerationCalculated = ioContext.getGeneration(); mNbDemesCalculated = 0; } if(++mNbDemesCalculated == mPopSize->size() && mOnlyVivarium->getWrappedValue()) { //Make heap of all individual in the vivarium for( unsigned int i = 0; i < ioContext.getVivarium().size(); ++i) { lTempPop.insert(lTempPop.end(), ioContext.getVivarium()[i]->begin(), ioContext.getVivarium()[i]->end()); } } else if(mOnlyVivarium->getWrappedValue()){ return; } else { //Process only this deme // Insert pointer of all the individuals of the deme in the buffer. lTempPop.insert(lTempPop.end(), ioDeme.begin(), ioDeme.end()); } // Make the buffer a STL heap with the fittest individual on the top. std::make_heap(lTempPop.begin(), lTempPop.end(), IsLessPointerPredicate()); for(unsigned int i = 0; i < mNumberIndividualPerDem->getWrappedValue(); ++i) { Individual::Handle lIndividual = NULL; if( !mKeepData->getWrappedValue() ) { //Strip the simulation data of the individual lIndividual = castHandleT<Individual>(ioDeme.getTypeAlloc()->cloneData(*lTempPop[0])); LogFitness::Handle lFitness = castHandleT<LogFitness>(lIndividual->getFitness()); lFitness->clearData(); } else { lIndividual = lTempPop[0]; } Beagle_LogObjectM( ioContext.getSystem().getLogger(), Logger::eStats, "history", "Beagle::LogIndividualDataOp", *lIndividual ); // STL heap pop of the best individual of the temporary buffer. std::pop_heap(lTempPop.begin(), lTempPop.end(), IsLessPointerPredicate()); lTempPop.pop_back(); } Beagle_StackTraceEndM("void LogIndividualDataOp::operate(Deme& ioDeme, Context& ioContext)"); }
/*! * \brief Apply the decimation operation on the deme. * \param ioDeme Current deme of individuals to decimate. * \param ioContext Context of the evolution. */ void DecimateOp::operate(Deme& ioDeme, Context& ioContext) { Beagle_StackTraceBeginM(); Beagle_ValidateParameterM((mDecimationRatio->getWrappedValue()<=1.0), mDecimationRatioName, "The decimation ratio must be less than or equal to 1.0."); Beagle_LogTraceM( ioContext.getSystem().getLogger(), "decimation", "Beagle::DecimateOp", std::string("Applying decimation operation on the ")+ uint2ordinal(ioContext.getDemeIndex()+1)+" deme" ); // Calculate the number of individuals to keep from the deme unsigned int lMu = 0; if(mDecimationRatio->getWrappedValue() == -1.0) { Beagle_AssertM(ioContext.getDemeIndex() < mPopSize->size()); lMu = (*mPopSize)[ioContext.getDemeIndex()]; } else { lMu = (unsigned int)std::ceil(mDecimationRatio->getWrappedValue()*float(ioDeme.size())); Beagle_AssertM(ioContext.getDemeIndex() < mPopSize->size()); int lDiffSize = (*mPopSize)[ioContext.getDemeIndex()] - lMu; if((lDiffSize >= -1) && (lDiffSize <= 1)) lMu = (*mPopSize)[ioContext.getDemeIndex()]; } Beagle_LogTraceM( ioContext.getSystem().getLogger(), "decimation", "Beagle::DecimateOp", std::string("Keeping ")+uint2str(lMu)+" of the "+uint2str(ioDeme.size())+ " individuals from the "+uint2ordinal(ioContext.getDemeIndex()+1)+" deme" ); // Check that the number of individuals to keep (mu) isn't greater than the deme size if(lMu > ioDeme.size()) { std::ostringstream lOSS; lOSS << "Warning: the actual population size (" << ioDeme.size(); lOSS << ") is less than the desired decimation size (" << lMu; lOSS << "). Decimation is thus not applied."; Beagle_LogBasicM( ioContext.getSystem().getLogger(), "decimation", "Beagle::DecimateOp", lOSS.str() ); return; } // Copy the individuals to be kept into the deme std::make_heap(ioDeme.begin(), ioDeme.end(), IsLessPointerPredicate()); Individual::Bag lSurvivors; for(unsigned int i=0; i<lMu; ++i) { lSurvivors.push_back(ioDeme.front()); std::pop_heap(ioDeme.begin(), (ioDeme.end()-i), IsLessPointerPredicate()); } ioDeme.clear(); ioDeme.insert(ioDeme.begin(), lSurvivors.begin(), lSurvivors.end()); Beagle_LogDetailedM( ioContext.getSystem().getLogger(), "decimation", "Beagle::DecimateOp", std::string("There are now ")+uint2str(ioDeme.size())+" individuals in the "+ uint2ordinal(ioContext.getDemeIndex()+1)+" deme" ); Beagle_StackTraceEndM("void DecimateOp::operate(Deme& ioDeme, Context& ioContext)"); }
/*! * \brief Apply the oversize replacement strategy operation on a deme. * \param ioDeme Reference to the deme on which the operation takes place. * \param ioContext Evolutionary context of the operation. */ void OversizeOp::operate(Deme& ioDeme, Context& ioContext) { Beagle_StackTraceBeginM(); Beagle_NonNullPointerAssertM(getRootNode()); Beagle_ValidateParameterM (mOversizeRatio->getWrappedValue() >= 1.0 || mOversizeRatio->getWrappedValue() == -1.0, mOversizeRatioName, "The oversize ratio must be greater than or equal to 1.0, or equal to -1.0."); Beagle_LogTraceM( ioContext.getSystem().getLogger(), "replacement-strategy", "Beagle::OversizeOp", string("Using oversize replacement strategy to process the ")+ uint2ordinal(ioContext.getDemeIndex()+1)+" deme" ); Beagle_LogObjectM( ioContext.getSystem().getLogger(), Logger::eTrace, "replacement-strategy", "Beagle::OversizeOp", (*this) ); RouletteT<unsigned int> lRoulette; buildRoulette(lRoulette, ioContext); // Calculate the increase in size (lambda) float lRatio = mOversizeRatio->getWrappedValue(); unsigned int lLambda; if (lRatio == -1.0) { // Using special ratio of -1.0 ensures deme grows to size specified in 'ec.pop.size' if (!ioContext.getSystem().getRegister().isRegistered("ec.pop.size")) { throw Beagle_RunTimeExceptionM(getName()+" requires register variable 'ec.pop.size'"); } UIntArray::Handle lPopSize = castHandleT<UIntArray> (ioContext.getSystem().getRegister().getEntry("ec.pop.size")); unsigned int lSpecifiedDemeSize = (*lPopSize)[ioContext.getDemeIndex()]; unsigned int lCurrentDemeSize = ioDeme.size(); if (lSpecifiedDemeSize < lCurrentDemeSize) { throw Beagle_RunTimeExceptionM (std::string("For the ")+uint2ordinal(ioContext.getDemeIndex()+1)+ " deme, the size specified in 'ec.pop.size' ("+uint2str(lSpecifiedDemeSize)+ ") is less than the current deme size ("+uint2str(lCurrentDemeSize)+ "). "+getName()+" can only increase the size of the deme. Consider using DecimateOp "+ "if you wish to decrease the size of the deme"); } lLambda = lSpecifiedDemeSize - lCurrentDemeSize; } else { // Using ratio to scale the deme's population lLambda = (unsigned int)ceil((lRatio-1.0)*float(ioDeme.size())); } Beagle_LogTraceM( ioContext.getSystem().getLogger(), "replacement-strategy", "Beagle::OversizeOp", string("Population will be increased in size by ")+uint2str(lLambda)+" individuals" ); // Create the new individuals. Individual::Bag lOffsprings; for(unsigned int i=0; i<lLambda; ++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); } // Add the new individuals into the deme. ioDeme.insert(ioDeme.end(), lOffsprings.begin(), lOffsprings.end()); Beagle_LogDetailedM( ioContext.getSystem().getLogger(), "replacement-strategy", "Beagle::OversizeOp", string("There are now ")+uint2str(ioDeme.size())+" individuals in the "+ uint2ordinal(ioContext.getDemeIndex()+1)+" deme" ); Beagle_StackTraceEndM("void OversizeOp::operate(Deme& ioDeme, Context& ioContext)"); }
/*! * \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(); }