/*! * \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 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(); }
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)"); }
int main (int argc, char** argv) { try { // 1. Build the system. System::Handle lSystem = new System; // 2. Build evaluation operator. DCDCBoost2xGAEvalOp::Handle lEvalOp = new DCDCBoost2xGAEvalOp; // 3. Instanciate the evolver. unsigned int lNbBits = (unsigned int)(NBSTATE*NBINPUTSYBMOLE + 1)*NBSWITCH; #ifdef USE_MPI MPI::GA::EvolverBitString::Handle lEvolver = new MPI::GA::EvolverBitString(lEvalOp,lNbBits); #else GA::EvolverBitString::Handle lEvolver = new GA::EvolverBitString(lEvalOp,lNbBits); #endif // 4. Initialize the vivarium GA::BitString::Alloc::Handle lBSAlloc = new GA::BitString::Alloc; LogFitness::Alloc::Handle lFitAlloc = new LogFitness::Alloc; Vivarium::Handle lVivarium = new Vivarium(lBSAlloc, lFitAlloc); // 5. Initialize the evolver and evolve the vivarium. lEvolver->initialize(lSystem, argc, argv); ////////////////////// //Read individual from file ostringstream lFilename; lFilename << "individual-ga-test.xml"; Individual::Handle lIndividual = new Individual(lBSAlloc); lIndividual->readFromFile(lFilename.str(), *lSystem); Beagle::Context::Handle lContext = castHandleT<Beagle::Context>(lSystem->getContextAllocator().allocate()); lContext->setSystemHandle(lSystem); lContext->setIndividualHandle(lIndividual); lContext->setIndividualIndex(0); LogFitness::Handle lFitness = castHandleT<LogFitness>(lEvalOp->evaluate(*lIndividual,*lContext)); cout << "\nResulting fitness: " << lFitness->getValue() << endl; ofstream lFitnessStream("fitness.xml"); lFitnessStream << lFitness->serialize() << endl; return 0; ///////////////////// lEvolver->evolve(lVivarium); } catch(Exception& inException) { inException.terminate(cerr); } catch(std::exception& inException) { cerr << "Standard exception catched:" << endl << flush; cerr << inException.what() << endl << flush; return 1; } return 0; }
/*! * \brief Apply the fitness invalidation operation on a breeding pool, returning a bred individual. * \param inBreedingPool Breeding pool to use for the breeding operation. * \param inChild Node handle associated to child node in the breeder tree. * \param ioContext Evolutionary context of the breeding operation. * \return Invalidated bred individual. */ Individual::Handle InvalidateFitnessOp::breed(Individual::Bag& inBreedingPool, BreederNode::Handle inChild, Context& ioContext) { Beagle_StackTraceBeginM(); Beagle_NonNullPointerAssertM(inChild); Beagle_NonNullPointerAssertM(inChild->getBreederOp()); Individual::Handle lBredIndividual = inChild->getBreederOp()->breed(inBreedingPool, inChild->getFirstChild(), ioContext); if((lBredIndividual->getFitness()!=NULL) && (lBredIndividual->getFitness()->isValid())) { Beagle_LogDebugM( ioContext.getSystem().getLogger(), "Invalidating the fitness of the following bred individual" ); Beagle_LogDebugM(ioContext.getSystem().getLogger(), *lBredIndividual); lBredIndividual->getFitness()->setInvalid(); } return lBredIndividual; 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 Read individuals of a bag. * \param inIter XML iterator to read the individuals from. * \param ioContext Evolutionary context. */ void IndividualBag::readIndividuals(PACC::XML::ConstIterator inIter, Context& ioContext) { Beagle_StackTraceBeginM(); clear(); Individual::Handle lPrevIndivHandle = ioContext.getIndividualHandle(); unsigned int lPrevIndivIndex = ioContext.getIndividualIndex(); for(PACC::XML::ConstIterator lIter=inIter; lIter; ++lIter) { if(lIter->getType() != PACC::XML::eData) continue; if(lIter->getValue() == "NullHandle") { push_back(NULL); continue; } else if(lIter->getValue() != "Individual") continue; Individual::Alloc::Handle lIndivAlloc = NULL; std::string lIndivTypeName = lIter->getAttribute("type"); const Factory& lFactory = ioContext.getSystem().getFactory(); if(lIndivTypeName.empty()) { lIndivAlloc = castHandleT<Individual::Alloc>(lFactory.getConceptAllocator("Individual")); } else { lIndivAlloc = castHandleT<Individual::Alloc>(lFactory.getAllocator(lIndivTypeName)); } Individual::Handle lReadIndiv = castHandleT<Individual>(lIndivAlloc->allocate()); const unsigned int lBackIndex = size(); push_back(lReadIndiv); ioContext.setIndividualHandle(lReadIndiv); ioContext.setIndividualIndex(lBackIndex); lReadIndiv->readWithContext(lIter, ioContext); } ioContext.setIndividualIndex(lPrevIndivIndex); ioContext.setIndividualHandle(lPrevIndivHandle); Beagle_StackTraceEndM(); }
/*! * \brief Test the fitness of a given individual. * \param inIndividual Handle to the individual to test. * \param ioSystem Handle to the system to use to test the individual. * \par Note: * This method is provided as a mean to test some individuals after an evolution. */ Fitness::Handle Beagle::MPI::EvaluationOp::test(Individual::Handle inIndividual, System::Handle ioSystem) { Beagle_LogInfoM( ioSystem->getLogger(), "evaluation", "Beagle::MPIEvaluationOp", std::string("Testing the following individual: ")+inIndividual->serialize() ); Context::Alloc::Handle lContextAlloc = castHandleT<Context::Alloc>(ioSystem->getContextAllocatorHandle()); Context::Handle lContext = castHandleT<Context>(lContextAlloc->allocate()); lContext->setSystemHandle(ioSystem); lContext->setIndividualHandle(inIndividual); Fitness::Handle lFitness = evaluate(*inIndividual, *lContext); Beagle_LogInfoM( ioSystem->getLogger(), "evaluation", "Beagle::MPIEvaluationOp", std::string("New fitness of the individual: ")+lFitness->serialize() ); return lFitness; }
/*! * \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 Apply the adaptation operation on a breeding pool. * \param inBreedingPool Breeding pool to give to the underlying breeding tree. * \param inChild Node handle associated to child node in the breeder tree. * \param ioContext Evolutionary context of the mutation operation. * \return Mutated individual. */ Individual::Handle ES::AdaptOneFifthRuleOp::breed(Individual::Bag& inBreedingPool, BreederNode::Handle inChild, Context& ioContext) { Beagle_StackTraceBeginM(); Beagle_NonNullPointerAssertM(inChild); Beagle_NonNullPointerAssertM(inChild->getBreederOp()); Individual::Handle lIndiv = inChild->getBreederOp()->breed(inBreedingPool, inChild->getFirstChild(), ioContext); // Look whether the mutation is successful. Fitness::Handle lFitParent = inBreedingPool[ioContext.getIndividualIndex()]->getFitness(); Fitness::Handle lFitChild = lIndiv->getFitness(); if(lFitChild != NULL) { // Check whether the mutation is successful or not. const bool lSuccessful = (*lFitChild) > (*lFitParent); if(lSuccessful) { ++mSuccessCount->getWrappedValue(); Beagle_LogVerboseM( ioContext.getSystem().getLogger(), "Successful mutation" ); } else { Beagle_LogVerboseM( ioContext.getSystem().getLogger(), "The mutation is not successful" ); } ++mMutationsCount->getWrappedValue(); // Adapt the sigma if the necessary number of observed mutations is reached. if(lSuccessful && (mMutationsCount->getWrappedValue()>=mAdaptationPeriod->getWrappedValue())) { const double lSuccessRate = double(mSuccessCount->getWrappedValue()) / double(mMutationsCount->getWrappedValue()); if(lSuccessRate > 0.2) { for(unsigned int i=0; i<mMutateGaussSigma->size(); ++i) { (*mMutateGaussSigma)[i] /= mSigmaAdaptFactor->getWrappedValue(); } Beagle_LogDetailedM( ioContext.getSystem().getLogger(), string("Increasing the sigma value by a factor ")+ dbl2str(1./mSigmaAdaptFactor->getWrappedValue()) ); Beagle_LogVerboseM( ioContext.getSystem().getLogger(), string("Sigma value after the increase: ")+mMutateGaussSigma->serialize() ); } else if(lSuccessRate < 0.2) { for(unsigned int i=0; i<mMutateGaussSigma->size(); ++i) { (*mMutateGaussSigma)[i] *= mSigmaAdaptFactor->getWrappedValue(); } Beagle_LogDetailedM( ioContext.getSystem().getLogger(), string("Reducing the sigma value by a factor ")+ dbl2str(mSigmaAdaptFactor->getWrappedValue()) ); Beagle_LogVerboseM( ioContext.getSystem().getLogger(), string("Sigma value after the reduction: ")+mMutateGaussSigma->serialize() ); } else { Beagle_LogDetailedM( ioContext.getSystem().getLogger(), "Sigma value unchanged" ); } } } return lIndiv; 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 NPGA2 multiobjective selection operator. * \param ioDeme Deme on which selection operator is applied. * \param ioContext Evolutionary context. */ void NPGA2Op::operate(Deme& ioDeme, Context& ioContext) { Beagle_StackTraceBeginM(); if(ioDeme.size() == 0) return; Beagle_LogTraceM( ioContext.getSystem().getLogger(), std::string("Applying NPGA2 multiobjective selection on the ")+ uint2ordinal(ioContext.getDemeIndex()+1)+" deme" ); std::vector<bool> lAlreadySelectedIndiv(ioDeme.size(), false); Individual::Bag lSelectedIndividual; const Factory& lFactory = ioContext.getSystem().getFactory(); // Generate new generation by selection for(unsigned int i=0; i<ioDeme.size(); ++i) { // First participant unsigned int lFirstParticipant = ioContext.getSystem().getRandomizer().rollInteger(0, ioDeme.size()-1); std::vector<unsigned int> lNDParticipants(1, lFirstParticipant); // Following participants to tournament for(unsigned int j=1; j<mNumberParticipants->getWrappedValue(); ++j) { unsigned int lParticipant = ioContext.getSystem().getRandomizer().rollInteger(0, ioDeme.size()-1); // Test if participant is dominated or dominate other participants bool lIsDominated = false; Fitness::Handle lPartFitness = ioDeme[lParticipant]->getFitness(); for(unsigned int k=0; k<lNDParticipants.size(); ++k) { Fitness::Handle lFitnessNDk = ioDeme[lNDParticipants[k]]->getFitness(); if(lPartFitness->isDominated(*lFitnessNDk)) { lIsDominated = true; } else if(lFitnessNDk->isDominated(*lPartFitness)) { lNDParticipants.erase(lNDParticipants.begin()+k); } } if(lIsDominated==false) lNDParticipants.push_back(lParticipant); } // Test if there is a tie. If so evaluate niche count. Beagle_AssertM(lNDParticipants.size() != 0); unsigned int lWinner = lNDParticipants[0]; if(lNDParticipants.size() > 1) { float lLowestNicheCount = evalNicheCount(*ioDeme[lNDParticipants[0]], lSelectedIndividual); for(unsigned int j=1; j<lNDParticipants.size(); ++j) { float lNicheCount = evalNicheCount(*ioDeme[lNDParticipants[j]], lSelectedIndividual); if(lNicheCount < lLowestNicheCount) { lLowestNicheCount = lNicheCount; lWinner = lNDParticipants[j]; } } } // Put winner in selected individual bag if(lAlreadySelectedIndiv[lWinner]) { std::string lIndividualType = ioDeme[lWinner]->getType(); Individual::Alloc::Handle lIndividualAlloc = castHandleT<Individual::Alloc>(lFactory.getAllocator(lIndividualType)); Individual::Handle lIndividual = castHandleT<Individual>(lIndividualAlloc->allocate()); lIndividual->copy(*ioDeme[lWinner], ioContext.getSystem()); lSelectedIndividual.push_back(lIndividual); Beagle_LogVerboseM( ioContext.getSystem().getLogger(), uint2ordinal(lWinner+1)+" individual selected again in NPGA2 selection process" ); } else { lSelectedIndividual.push_back(ioDeme[lWinner]); lAlreadySelectedIndiv[lWinner] = true; Beagle_LogVerboseM( ioContext.getSystem().getLogger(), uint2ordinal(lWinner+1)+" individual selected in NPGA2 selection process" ); } } // Copy selected individuals into deme for(unsigned int j=0; j<ioDeme.size(); ++j) ioDeme[j] = lSelectedIndividual[j]; Beagle_StackTraceEndM(); }
/*! * \brief Apply the evaluation operation on a breeding pool, returning a evaluated bred individual. * \param inBreedingPool Breeding pool to use for the breeding operation. * \param inChild Node handle associated to child node in the breeder tree. * \param ioContext Evolutionary context of the breeding operation. * \return Evaluated bred individual. */ Individual::Handle Beagle::MPI::EvaluationOp::breed(Individual::Bag& inBreedingPool, BreederNode::Handle inChild, Context& ioContext) { Beagle_NonNullPointerAssertM(inChild); Deme& lDeme = *ioContext.getDemeHandle(); if(lDeme.getStats()->isValid()) { ioContext.setProcessedDeme(0); if((ioContext.getGeneration()!=0) && (lDeme.getStats()->existItem("total-processed"))) { ioContext.setTotalProcessedDeme((unsigned int)lDeme.getStats()->getItem("total-processed")); } else ioContext.setTotalProcessedDeme(0); lDeme.getStats()->setInvalid(); if(ioContext.getDemeIndex()==0) { Stats& lVivaStats = *ioContext.getVivarium().getStats(); ioContext.setProcessedVivarium(0); if((ioContext.getGeneration()!=0) && (lVivaStats.existItem("total-processed"))) { ioContext.setTotalProcessedVivarium((unsigned int)lVivaStats.getItem("total-processed")); } else ioContext.setTotalProcessedVivarium(0); lVivaStats.setInvalid(); } } Beagle_NonNullPointerAssertM(inChild); Beagle_NonNullPointerAssertM(inChild->getBreederOp()); Individual::Handle lBredIndividual = inChild->getBreederOp()->breed(inBreedingPool, inChild->getFirstChild(), ioContext); if((lBredIndividual->getFitness()==NULL) || (lBredIndividual->getFitness()->isValid()==false)) { Beagle_LogVerboseM( ioContext.getSystem().getLogger(), "evaluation", "Beagle::MPIEvaluationOp", "Evaluating the fitness of a new bred individual" ); individualEvaluation(*lBredIndividual, ioContext); // lBredIndividual->setFitness(evaluate(*lBredIndividual, ioContext)); // lBredIndividual->getFitness()->setValid(); ioContext.setProcessedDeme(ioContext.getProcessedDeme()+1); ioContext.setTotalProcessedDeme(ioContext.getTotalProcessedDeme()+1); ioContext.setProcessedVivarium(ioContext.getProcessedVivarium()+1); ioContext.setTotalProcessedVivarium(ioContext.getTotalProcessedVivarium()+1); Beagle_LogVerboseM( ioContext.getSystem().getLogger(), "evaluation", "Beagle::MPIEvaluationOp", std::string("The individual fitness value is: ")+ lBredIndividual->getFitness()->serialize() ); if(mDemeHOFSize->getWrappedValue() > 0) { Beagle_LogVerboseM( ioContext.getSystem().getLogger(), "evaluation", "Beagle::MPIEvaluationOp", "Updating the deme hall-of-fame" ); lDeme.getHallOfFame().updateWithIndividual(mDemeHOFSize->getWrappedValue(), *lBredIndividual, ioContext); } if(mVivaHOFSize->getWrappedValue() > 0) { Beagle_LogVerboseM( ioContext.getSystem().getLogger(), "evaluation", "Beagle::MPIEvaluationOp", "Updating the vivarium hall-of-fame" ); ioContext.getVivarium().getHallOfFame().updateWithIndividual(mVivaHOFSize->getWrappedValue(), *lBredIndividual, ioContext); } } return lBredIndividual; }
void Beagle::MPI::EvaluationOp::evaluatorOperate(Deme& ioDeme, Context& ioContext) { try { //char lMessage[4096]; int lMessageSize; MPI_Status lStatus; int lSource; bool lDone = false; while(!lDone) { //Receive an individual to evaluate MPI_Recv(&lMessageSize, 1, MPI_INT, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &lStatus); lSource = lStatus.MPI_SOURCE; if(lStatus.MPI_TAG == eEvolutionEnd) { Beagle_LogDetailedM( ioContext.getSystem().getLogger(), "evaluation", "Beagle::MPIEvaluationOp", std::string("End of evolution received from process ") + int2str(lSource) ); lDone = true; } else { char *lMessage = new char[lMessageSize]; unsigned int lGeneration; MPI_Recv(lMessage, lMessageSize, MPI_CHAR, lSource, MPI_ANY_TAG, MPI_COMM_WORLD, &lStatus); MPI_Recv(&lGeneration, 1, MPI_INT, lSource, MPI_ANY_TAG, MPI_COMM_WORLD, &lStatus); ioContext.setGeneration(lGeneration); Beagle_LogTraceM( ioContext.getSystem().getLogger(), "evaluation", "Beagle::MPIEvaluationOp", std::string("Evaluating individual send from process ") + int2str(lSource) ); //Parse the received individual std::istringstream lStreamIn(lMessage); PACC::XML::Document lXMLParser; lXMLParser.parse(lStreamIn); PACC::XML::ConstIterator lIndividualRootNode = lXMLParser.getFirstRoot(); //Read the received individual ioContext.getDeme().resize(0); Individual::Handle lIndividual = castHandleT<Individual>(ioContext.getDeme().getTypeAlloc()->allocate()); lIndividual->readWithContext(lIndividualRootNode,ioContext); ioContext.setIndividualHandle(lIndividual); ioContext.setIndividualIndex(0); // Beagle_LogDebugM( // ioContext.getSystem().getLogger(), // "evaluation", "Beagle::MPIEvaluationOp", // std::string("Individual received: ") + lIndividual->serialize() // ); //Free message string delete [] lMessage; //Evaluated the fitness of the received individual Fitness::Handle lFitness = evaluate(*lIndividual, ioContext); //Send back the fitness std::ostringstream lStreamOut; PACC::XML::Streamer lXMLStream(lStreamOut); lFitness->write(lXMLStream); //std::cout << "Sending fitness of size " << lStreamOut.str().size()+1 << ":" << std::endl << lStreamOut.str() << std::endl; lMessageSize = lStreamOut.str().size()+1; Beagle_LogTraceM( ioContext.getSystem().getLogger(), "evaluation", "Beagle::MPIEvaluationOp", std::string("Sending back fitness") ); MPI_Send(&lMessageSize, 1, MPI_INT, lSource, eMessageSize, MPI_COMM_WORLD); MPI_Send(const_cast<char*>(lStreamOut.str().data()), lMessageSize, MPI_CHAR, lSource, eFitness, MPI_COMM_WORLD); } } } catch(Exception& inException) { std::cerr << "Exception catched in evaluator:" << std::endl << std::flush; std::cerr << inException.what() << std::endl << std::flush; exit(1); } catch(std::exception& inException) { std::cerr << "Standard exception catched in evaluator:" << std::endl << std::flush; std::cerr << inException.what() << std::endl << std::flush; exit(1); } }