/*! * \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 Check if the maximum fitness value is reached. * \param inDeme Actual deme of the evolution. * \param ioContext Actual evolution context. * \return True if the ending criterion is reached, false if not. */ bool TermMaxFitnessOp::terminate(const Deme& inDeme, Context& ioContext) { Beagle_StackTraceBeginM(); for(unsigned int i=0; i<inDeme.size(); ++i) { FitnessSimple::Handle lFitness = castHandleT<FitnessSimple>(inDeme[i]->getFitness()); if(lFitness->isValid() && lFitness->getValue() >= mMaxFitness->getWrappedValue()) { Beagle_LogInfoM( ioContext.getSystem().getLogger(), std::string("Maximum fitness value (") + dbl2str(mMaxFitness->getWrappedValue()) + std::string(") termination criterion reached by the ") + uint2ordinal(i+1) + std::string(" individual (") + dbl2str(lFitness->getValue()) + std::string(")") ); ioContext.setTerminationSuccessful(); return true; } } Beagle_LogTraceM( ioContext.getSystem().getLogger(), std::string("Maximum fitness value (") + dbl2str(mMaxFitness->getWrappedValue()) + std::string(") termination criterion not reached ") ); return false; Beagle_StackTraceEndM(); }
void Beagle::MPI::EvaluationOp::evolverOperate(Deme& ioDeme, Context& ioContext) { Beagle_LogTraceM( ioContext.getSystem().getLogger(), "evaluation", "Beagle::MPIEvaluationOp", std::string("Evaluating the individuals fitness of the ")+ uint2ordinal(ioContext.getDemeIndex()+1)+" deme" ); if(ioDeme.size() == 0) return; Individual::Handle lOldIndividualHandle = ioContext.getIndividualHandle(); unsigned int lOldIndividualIndex = ioContext.getIndividualIndex(); ioContext.setProcessedDeme(0); if((ioContext.getGeneration()!=0) && (ioDeme.getStats()->existItem("total-processed"))) { ioContext.setTotalProcessedDeme((unsigned int)ioDeme.getStats()->getItem("total-processed")); } else ioContext.setTotalProcessedDeme(0); ioDeme.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(); } distributeDemeEvaluation(ioDeme, ioContext); ioContext.setIndividualIndex(lOldIndividualIndex); ioContext.setIndividualHandle(lOldIndividualHandle); if(mDemeHOFSize->getWrappedValue() > 0) { Beagle_LogDetailedM( ioContext.getSystem().getLogger(), "evaluation", "Beagle::MPIEvaluationOp", "Updating the deme's hall-of-fame" ); ioDeme.getHallOfFame().updateWithDeme(mDemeHOFSize->getWrappedValue(), ioDeme, ioContext); ioDeme.getHallOfFame().log(Logger::eVerbose, ioContext); } if(mVivaHOFSize->getWrappedValue() > 0) { Beagle_LogDetailedM( ioContext.getSystem().getLogger(), "evaluation", "Beagle::MPIEvaluationOp", "Updating the vivarium's hall-of-fame" ); ioContext.getVivarium().getHallOfFame().updateWithDeme(mVivaHOFSize->getWrappedValue(), ioDeme, ioContext); ioContext.getVivarium().getHallOfFame().log(Logger::eVerbose, ioContext); } }
/*! * \brief Distribute groups of individuals to evaluators nodes childs. * \param ioDeme Current deme to execute the operator. * \param ioContext Current context to execute the operator. * This function distributed individuals to the evolver's evaluators. * * It first checks if the deme has a \ref ProcessingBuffer. The buffer * is used to memorize which individuals had invalid fitness, since the * function only distributes individuals that were modified during the * current generation. Once the buffer is filled, the individuals are * distributed to evaluator. * The number of individuals an evaluato will received is based on this * formula : * \f[ NbIndividuals = \left\{ \begin{array}{lr} \frac{BufferSize}{NbEvaluators} + 1, & EvaluatorRank > BufferSize \pmod{NbEvaluators} \\ \frac{BufferSize}{NbEvaluators}, & else \end{array} \right. \f] * * The function write the individuals in a streamer. The streamer opening * tag is <Population> so the evaluator can directly read the string at * its reception as a deme. * * The string are sent using a non-blocking send function, so the function * doesn't have to wait for the transaction to be completed before starting * to build another packet of individuals. The function ends when all * packets have been sent. */ void HPC::DistributeDemeToEvaluatorsOp::operate(Deme& ioDeme, Context& ioContext) { Beagle_StackTraceBeginM(); unsigned int lNbEvaluators = mComm->getNbrOfRelation("Child"); ProcessingBuffer::Handle lBuffer = castHandleT<ProcessingBuffer>(ioDeme.getMember("ProcessingBuffer")); if(lBuffer==0){ lBuffer = new ProcessingBuffer; ioDeme.addMember(lBuffer); } lBuffer->clear(); for(unsigned int i = 0; i < ioDeme.size(); ++i){ if((ioDeme[i]->getFitness() == 0) || (ioDeme[i]->getFitness()->isValid() == false)){ lBuffer->push_back(ioDeme[i], i); } } unsigned int lNbIndividualInt = lBuffer->size() / lNbEvaluators; unsigned int lNbIndividualFrac = lBuffer->size() % lNbEvaluators; unsigned int lNbIndividualTotal = 0; unsigned int lNbIndividual = 0; std::vector<std::string> lStreams(lNbEvaluators); MPICommunication::Request::Bag lRequests(lNbEvaluators); for(unsigned int i = 0; i < lNbEvaluators; ++i){ lNbIndividual = lNbIndividualInt; if(i < lNbIndividualFrac) lNbIndividual++; std::ostringstream lOutStream; PACC::XML::Streamer lStreamer(lOutStream); lStreamer.openTag("Population"); for(int j = 0; j < lNbIndividual; ++j){ (*lBuffer)[j+lNbIndividualTotal]->write(lStreamer, false); } lStreamer.closeTag(); lStreams[i] = lOutStream.str(); lRequests[i] = new MPICommunication::Request; mComm->sendNonBlocking(lStreams[i], lRequests[i], "Individuals", "Child", i); lNbIndividualTotal += lNbIndividual; Beagle_LogDetailedM( ioContext.getSystem().getLogger(), "distribute", "Beagle::HPC::DistributeDemeToEvaluatorsOp", std::string("Evolver send fractionnal Deme to his ")+uint2ordinal(i+1)+ " evaluator" ); } mComm->waitAll(lRequests); Beagle_StackTraceEndM("DistributeDemeToEvaluatorsOp::operate(Deme& ioDeme, Context& ioContext)"); }
bool TreeSTag::findMatchingTopology(Deme& ioDeme, Context& ioContext, TreeSTag::Handle& outTree) { for(unsigned int i=0; i<ioDeme.size(); ++i) { TreeSTag::Handle lTree = castHandleT<TreeSTag>((*(ioDeme)[i])[0]); if(lTree != this) { if(this->compareTopology(*lTree)) { outTree = lTree; return true; } } } return false; }
/*! * \brief Read individuals from a given file to seed the evolution. * \param inFileName File name to read seeds individual from. * \param ioDeme Deme to initialize with seeds. * \param ioContext Evolutionary context. * \return Number of seeds read. * * Seeds file format is quite simple: XML file with "Beagle" root tag, and then a * "Seeds" tag with in it the individuals representation to read. Here is a * seeds file example with one individual in it. * \verbatim <?xml version="1.0" encoding="ISO-8859-1"?> <Beagle> <Seeds> <Individual> <Genotype type="bitstring">11111</Genotype> </Individual> </Seeds> </Beagle> \endverbatim * If there is less individuals in the seed file than the population size, the * remaining individuals are initialized as usual. If there is more individuals * than needed, the last individuals of the seeds file are ignored. If more than one * deme is used in the evolution, each deme will be seeded with the same seeds file. * */ unsigned int InitializationOp::readSeeds(std::string inFileName, Deme& ioDeme, Context& ioContext) { Beagle_StackTraceBeginM(); #ifdef BEAGLE_HAVE_LIBZ igzstream lIFStream(inFileName.c_str()); #else // BEAGLE_HAVE_LIBZ std::ifstream lIFStream(inFileName.c_str()); #endif // BEAGLE_HAVE_LIBZ PACC::XML::Document lParser; try { lParser.parse(lIFStream, inFileName); } catch(IOException& inExcept) { std::ostringstream lOSS; lOSS << "The seeds file is invalid: " << inExcept.what(); throw Beagle_IOExceptionMessageM(lOSS.str()); } unsigned int lReadIndividuals=0; unsigned int lOldIndivIndex = ioContext.getIndividualIndex(); Individual::Handle lOldIndivHandle = ioContext.getIndividualHandle(); for(PACC::XML::ConstIterator lNode=lParser.getFirstRoot(); lNode; ++lNode) { if((lNode->getType()==PACC::XML::eData) && (lNode->getValue()=="Beagle")) { for(PACC::XML::ConstIterator lChild=lNode->getFirstChild(); lChild; ++lChild) { if((lChild->getType()==PACC::XML::eData) && (lChild->getValue()=="Seeds")) { for(PACC::XML::ConstIterator lChild2=lChild->getFirstChild(); lChild2; ++lChild2) { if((lChild2->getType()==PACC::XML::eData) && (lChild2->getValue()=="Individual")) { if(lReadIndividuals >= ioDeme.size()) break; Beagle_NonNullPointerAssertM(ioDeme[lReadIndividuals]); ioContext.setIndividualIndex(lReadIndividuals); ioContext.setIndividualHandle(ioDeme[lReadIndividuals]); Beagle_LogVerboseM( ioContext.getSystem().getLogger(), std::string("Reading the ")+uint2ordinal(lReadIndividuals+1)+ std::string(" individual from seeds file") ); ioDeme[lReadIndividuals]->readWithContext(lChild2, ioContext); Beagle_LogDebugM(ioContext.getSystem().getLogger(), *ioDeme[lReadIndividuals]); ++lReadIndividuals; } } } } } } ioContext.setIndividualHandle(lOldIndivHandle); ioContext.setIndividualIndex(lOldIndivIndex); return lReadIndividuals; Beagle_StackTraceEndM(); }
/*! * \brief Invalidates the fitness of every individual in ioDeme. * \param ioDeme The deme to operate on. * \param ioContext Evolutionary context. */ void InvalidateFitnessOp::operate(Deme& ioDeme, Context& ioContext) { Beagle_StackTraceBeginM(); Beagle_LogTraceM( ioContext.getSystem().getLogger(), "Invalidating the fitness of every individual in the " << uint2ordinal(ioContext.getDemeIndex()+1) << " deme" ); for(unsigned int i=0; i<ioDeme.size(); i++) { if(ioDeme[i]->getFitness() != NULL) { Beagle_LogDebugM( ioContext.getSystem().getLogger(), "Invalidating the fitness of the " << uint2ordinal(i+1) << " individual of the " << uint2ordinal(ioContext.getDemeIndex()+1) << " deme" ); ioDeme[i]->getFitness()->setInvalid(); } } Beagle_StackTraceEndM(); }
/*! * \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 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 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 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 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 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(); }
/*! * \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 Update covariance matrix, cumulation path and other CMA values. * \param ioDeme Deme to use to update CMA values. * \param ioContext Evolutionary context. * \param inN Dimensionality of the problem. * \param inMuEff Effective mu. * \param inSelectionWeights Selection weights. * \param ioCMAValues Reference to CMA values. * * This routine is mostly inspired from matlab routine cmaes.m and the document * "The CMA Evolution Strategy: A Tutorial" (October 15, 2004), both * from Nikolaus Hansen. * See http://www.bionik.tu-berlin.de/user/niko/cmaes_inmatlab.html */ void CMA::MuWCommaLambdaCMAFltVecOp::updateValues(Deme& ioDeme, Context& ioContext, unsigned int inN, double inMuEff, const Vector& inSelectionWeights, CMA::CMAValues& ioCMAValues) const { Beagle_StackTraceBeginM(); // Log messages Beagle_LogTraceM( ioContext.getSystem().getLogger(), "Updating covariance matrix, sigma, and cumulation paths of CMA-ES." ); // Compute some constants const double lCC = 4.0 / (double(inN) + 4.0); const double lCS = (inMuEff+2.0) / (double(inN)+inMuEff+3.0); const double lMuCov = inMuEff; double lCCov = ((2.0*inMuEff)-1.0) / (((double(inN)+2.0)*(double(inN)+2.0)) + inMuEff); lCCov = ((1.0/lMuCov) * (2.0/((double(inN)+1.414)*(double(inN)+1.414)))) + ((1.0-(1.0/lMuCov)) * minOf(1.0,lCCov)); double lDamps = std::sqrt((inMuEff-1.0) / (double(inN)+1.0)) - 1.0; lDamps = 1.0 + (2.0*maxOf(0.0,lDamps)) + lCS; const double lChiN = std::sqrt(double(inN)) * (1.0 - (0.25/double(inN)) + (1.0/(21.0*double(inN)*double(inN)))); // Compute new xmean Vector lXmean_new(inN, 0.0); for(unsigned int i=0; i<ioDeme.size(); ++i) { FltVec::FloatVector::Handle lVecI = castHandleT<FltVec::FloatVector>((*ioDeme[i])[0]); for(unsigned int j=0; j<inN; ++j) lXmean_new[j] += (inSelectionWeights[i] * (*lVecI)[j]); } // Compute zmean Vector lZmean(inN,0.0); const double lSigma=ioCMAValues.mSigma.getWrappedValue(); for(unsigned int i=0; i<inN; ++i) { lZmean[i] = (lXmean_new[i] - ioCMAValues.mXmean[i]) / lSigma; } Matrix lBt; ioCMAValues.mB.transpose(lBt); lZmean = lBt * lZmean; for(unsigned int i=0; i<inN; ++i) lZmean[i] /= ioCMAValues.mD[i]; // Update cumulation paths Matrix lBD(inN,inN,0.0); for(unsigned int i=0; i<inN; ++i) { for(unsigned int j=0; j<inN; ++j) lBD(j,i) = ioCMAValues.mB(j,i) * ioCMAValues.mD[i]; } Vector lBZm; ioCMAValues.mB.multiply((Matrix&)lBZm, lZmean); lBZm *= std::sqrt(lCS * (2.0-lCS) * inMuEff); ioCMAValues.mPS *= (1.0-lCS); ioCMAValues.mPS += lBZm; double lPSnorm = 0.0; for(unsigned int i=0; i<ioCMAValues.mPS.size(); ++i) lPSnorm += (ioCMAValues.mPS[i] * ioCMAValues.mPS[i]); lPSnorm = std::sqrt(lPSnorm); const double lHLeft = lPSnorm / std::sqrt(1.0-std::pow(1.0-lCS, 2.0*double(ioContext.getGeneration()))); const double lHRight = (1.5+(1.0/(double(inN)-0.5))) * lChiN; const bool lHSig = (lHLeft<lHRight); ioCMAValues.mPC *= (1.0-lCC); if(lHSig) { // Vector lBDZm; // lBD.multiply((Matrix&)lBDZm, lZmean); // lBDZm *= std::sqrt(lCC * (2.0-lCC) * inMuEff); // ioCMAValues.mPC += lBDZm; Vector lXdiff = lXmean_new - ioCMAValues.mXmean; lXdiff *= (std::sqrt(lCC * (2.0-lCC) * inMuEff) / lSigma); ioCMAValues.mPC += lXdiff; } else { Beagle_LogTraceM( ioContext.getSystem().getLogger(), "CMA-ES p_c cumulation path update stalled" ); } // Adapt covariance matrix C Matrix lC, lBDt; lBD.transpose(lBDt); lBD.multiply(lC, lBDt); double lAttnC = (1.0-lCCov); // Attenuation factor if(lHSig == false) lAttnC += (lCCov * lCC * (2.0-lCC) / lMuCov); Matrix lR1Upd; // Rank one update ioCMAValues.mPC.transpose(lR1Upd); lR1Upd = ioCMAValues.mPC * lR1Upd; lR1Upd *= (lCCov / lMuCov); Matrix lRMuUpd(inN,inN,0.0); // Rank Mu update for(unsigned int i=0; i<ioDeme.size(); ++i) { FltVec::FloatVector::Handle lVecI = castHandleT<FltVec::FloatVector>((*ioDeme[i])[0]); Vector lX_I(lVecI->size()); for(unsigned int j=0; j<lVecI->size(); ++j) lX_I[j] = (*lVecI)[j]; lX_I -= ioCMAValues.mXmean; Matrix lX_It; lX_I.transpose(lX_It); lX_It *= inSelectionWeights[i]; lRMuUpd += (lX_I * lX_It); } lRMuUpd *= (lCCov * (1.0 - (1.0/lMuCov)) / (lSigma * lSigma)); lC *= lAttnC; // Attenuate old matrix lC += lR1Upd; // Add rank one update lC += lRMuUpd; // Add rank mu update // Adapt step size sigma ioCMAValues.mSigma.getWrappedValue() *= std::exp((lCS/lDamps) * ((lPSnorm/lChiN)-1.0)); // Update B and D from C for(unsigned int i=1; i<inN; ++i) { for(unsigned int j=0; j<i; ++j) lC(i,j) = lC(j,i); // Enforce symetry } lC.computeEigens(ioCMAValues.mD, ioCMAValues.mB); // Principal component analysis // Adjust D as standard deviation for(unsigned int i=0; i<inN; ++i) { ioCMAValues.mD[i] = std::sqrt(ioCMAValues.mD[i]); } // Log updated parameters. Beagle_LogTraceM( ioContext.getSystem().getLogger(), std::string("CMA-ES updated B matrix (principal components): ")+ioCMAValues.mB.serialize() ); Beagle_LogTraceM( ioContext.getSystem().getLogger(), std::string("CMA-ES updated D vector (standard deviations): ")+ioCMAValues.mD.serialize() ); Beagle_LogTraceM( ioContext.getSystem().getLogger(), std::string("CMA-ES updated sigma: ")+ioCMAValues.mSigma.serialize() ); Beagle_LogVerboseM( ioContext.getSystem().getLogger(), std::string("CMA-ES updated p_c vector (covariance cumulation path): ")+ioCMAValues.mPC.serialize() ); Beagle_LogVerboseM( ioContext.getSystem().getLogger(), std::string("CMA-ES updated p_s vector (sigma cumulation path): ")+ioCMAValues.mPS.serialize() ); Beagle_StackTraceEndM(); }
/*! * \brief Apply the CMA-ES (Mu_W+Lambda) 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. * \throw Beagle::ValidationException If a parameter is missing or have a bad value. * \throw Beagle::AssertException If an invalid condition appears. */ void CMA::MuWCommaLambdaCMAFltVecOp::operate(Deme& ioDeme, Context& ioContext) { Beagle_StackTraceBeginM(); // Get real popsize and size of float vectors from register. UIntArray::Handle lPopSize; if(ioContext.getSystem().getRegister().isRegistered("ec.pop.size")) { lPopSize = castHandleT<UIntArray>(ioContext.getSystem().getRegister()["ec.pop.size"]); } else { std::ostringstream lOSS; lOSS << "Population size parameter 'ec.pop.size' is not found in register!"; throw ValidationException(lOSS.str()); } const unsigned int lDemeSize = (*lPopSize)[ioContext.getDemeIndex()]; UInt::Handle lFloatVectorSize; if(ioContext.getSystem().getRegister().isRegistered("ga.init.vectorsize")) { lFloatVectorSize = castHandleT<UInt>(ioContext.getSystem().getRegister()["ga.init.vectorsize"]); } else { std::ostringstream lOSS; lOSS << "GA::MuWCommaLambdaCMAFltVecOp must be used in fixed-lenght float vector "; lOSS << "individuals. Parameter 'ga.init.vectorsize' is not in register, "; lOSS << "while it is needed to set initial size of the different CMA-ES matrices "; lOSS << "and vectors."; throw ValidationException(lOSS.str()); } const unsigned int lN=lFloatVectorSize->getWrappedValue(); // Get the appropriate CMA values from the CMA holder component. CMA::CMAValues& lValues = getCMAValues(ioContext.getDemeIndex(),lN,ioContext); // Compute weights and effective mu Vector lWeight; double lMuEff = 0.0; lMuEff = generateSelectionWeights(lDemeSize, lWeight); if(ioDeme.size() == 1) lMuEff = 1.; // If the replacement strategy possess a breeder tree if(getRootNode()!=NULL) { // Generate new children. const unsigned int lLambda = (unsigned int)std::ceil(mLMRatio->getWrappedValue()*double(lDemeSize)); generateChildren(ioDeme, ioContext, lLambda, lN, lValues, lWeight); // Check if all individuals have known fitness. for(unsigned int i=0; i<ioDeme.size(); ++i) { // If there is one invalid fitness, we should exit. // Evaluation will be taken elsewhere (we hope), and actual operator will be recalled. if((ioDeme[i]->getFitness()==NULL) || (ioDeme[i]->getFitness()->isValid()==false)) return; } } // Keep mu best children Beagle_AssertM(ioDeme.size() > lDemeSize); std::sort(ioDeme.begin(), ioDeme.end(), IsMorePointerPredicate()); ioDeme.resize(lDemeSize); // Update CMA-ES values. updateValues(ioDeme, ioContext, lN, lMuEff, lWeight, lValues); Beagle_StackTraceEndM(); }
/*! * \brief Apply NSGA2 multiobjective selection operator as a replacement strategy. * \param ioDeme Deme on which selection operator is applied. * \param ioContext Evolutionary context. */ void EMO::NSGA2Op::applyAsReplacementStrategy(Deme& ioDeme, Context& ioContext) { Beagle_StackTraceBeginM(); Beagle_LogTraceM( ioContext.getSystem().getLogger(), std::string("Processing using NSGA2 replacement strategy the ")+ uint2ordinal(ioContext.getDemeIndex()+1)+" deme" ); Beagle_LogTraceM(ioContext.getSystem().getLogger(), (*this)); // Generate a new generation of individuals, merged with the actual one. const unsigned int lLambda = (unsigned int)std::ceil(mLMRatio->getWrappedValue()*float(ioDeme.size())); Beagle_LogVerboseM( ioContext.getSystem().getLogger(), "Generating " << lLambda << " offsprings using breeder tree" ); RouletteT<unsigned int> lRoulette; buildRoulette(lRoulette, ioContext); Individual::Bag lOffsprings(ioDeme); 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); } // Fast non-dominated sorting, followed by insertion of the first Pareto fronts. Beagle_LogVerboseM( ioContext.getSystem().getLogger(), "Applying fast non-dominated sorting on the union of parents and offsprings individual" ); NSGA2Op::Fronts lParetoFronts; sortFastND(lParetoFronts, ioDeme.size(), lOffsprings, ioContext); unsigned int lIndexDeme=0; for(unsigned int j=0; j<(lParetoFronts.size()-1); ++j) { for(unsigned int k=0; k<lParetoFronts[j].size(); ++k) { ioDeme[lIndexDeme++] = lOffsprings[lParetoFronts[j][k]]; } } // Insertion of the last Pareto front, using crowding distance Individual::Bag lLastFrontIndiv; for(unsigned int l=0; l<lParetoFronts.back().size(); ++l) { lLastFrontIndiv.push_back(lOffsprings[lParetoFronts.back()[l]]); } NSGA2Op::Distances lDistances; Beagle_LogVerboseM( ioContext.getSystem().getLogger(), "Computing crowding distance on the " << uint2ordinal(lParetoFronts.size()) << " Pareto front, which is made of " << lParetoFronts.back().size() << " individuals" ); evalCrowdingDistance(lDistances, lLastFrontIndiv); for(unsigned int m=0; lIndexDeme<ioDeme.size(); ++m) { ioDeme[lIndexDeme++] = lLastFrontIndiv[lDistances[m].second]; } 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(); }
void StatsCalcFitnessNMSEOp::calculateStatsDeme(Stats &outStats, Deme &ioDeme, Context &ioContext) const { Beagle_StackTraceBeginM(); outStats.clear(); outStats.clearItems(); int outputs = mConfig->getOutputs().size(); outStats.addItem("processed", ioContext.getProcessedDeme()); outStats.addItem("total-processed", ioContext.getTotalProcessedDeme()); if(ioDeme.size() == 0) { outStats.setGenerationValues(Beagle::string("deme")+uint2str(ioContext.getDemeIndex()+1), ioContext.getGeneration(), 0, true); outStats.resize(3+outputs*2); outStats[0].mId = "NMSE"; outStats[0].mAvg = 0.0; outStats[0].mStd = 0.0; outStats[0].mMax = 0.0; outStats[0].mMin = 0.0; outStats[1].mId = "treedepth"; outStats[1].mAvg = 0.0; outStats[1].mStd = 0.0; outStats[1].mMax = 0.0; outStats[1].mMin = 0.0; outStats[2].mId = "treesize"; outStats[2].mAvg = 0.0; outStats[2].mStd = 0.0; outStats[2].mMax = 0.0; outStats[2].mMin = 0.0; for(int i=0; i<outputs; ++i) { int nr = 3 + i*2; outStats[nr].mId = "y" + int2str(i) + "-NMSE"; outStats[nr].mAvg = 0.0; outStats[nr].mStd = 0.0; outStats[nr].mMax = 0.0; outStats[nr].mMin = 0.0; ++nr; outStats[nr].mId = "y" + int2str(i) + "-MSE"; outStats[nr].mAvg = 0.0; outStats[nr].mStd = 0.0; outStats[nr].mMax = 0.0; outStats[nr].mMin = 0.0; } return; } const GP::Deme& gpDeme = castObjectT<const GP::Deme&>(ioDeme); const FitnessNMSE::Handle firstIndivFitness = castHandleT<FitnessNMSE>(ioDeme[0]->getFitness()); if(ioDeme.size() == 1) { outStats.setGenerationValues(Beagle::string("deme")+uint2str(ioContext.getDemeIndex()+1), ioContext.getGeneration(), 1, true); outStats.resize(3+outputs*2); outStats[0].mId = "NMSE"; outStats[0].mAvg = firstIndivFitness->getNMSE(); outStats[0].mStd = 0.0; outStats[0].mMax = firstIndivFitness->getNMSE(); outStats[0].mMin = firstIndivFitness->getNMSE(); outStats[1].mId = "treedepth"; outStats[1].mAvg = gpDeme[0]->getMaxTreeDepth(); outStats[1].mStd = 0.0; outStats[1].mMax = outStats[1].mAvg; outStats[1].mMin = outStats[1].mAvg; outStats[2].mId = "treesize"; outStats[2].mAvg = gpDeme[0]->getTotalNodes(); outStats[2].mStd = 0.0; outStats[2].mMax = outStats[2].mAvg; outStats[2].mMin = outStats[2].mAvg; for(int i=0; i<outputs; ++i) { int nr = 3 + i*2; double nmse = (*firstIndivFitness)[i].nmse; double mse = (*firstIndivFitness)[i].mse; outStats[nr].mId = "y" + int2str(i) + "-NMSE"; outStats[nr].mAvg = nmse; outStats[nr].mStd = 0.0; outStats[nr].mMax = nmse; outStats[nr].mMin = nmse; ++nr; outStats[nr].mId = "y" + int2str(i) + "-MSE"; outStats[nr].mAvg = mse; outStats[nr].mStd = 0.0; outStats[nr].mMax = mse; outStats[nr].mMin = mse; } return; } double sum = firstIndivFitness->getNMSE(); double pow2sum = pow2Of<double>(sum); double max = sum; double min = sum; std::vector<double> sumNMSE(outputs, 0); std::vector<double> pow2sumNMSE(outputs, 0); std::vector<double> maxNMSE(outputs, 0); std::vector<double> minNMSE(outputs, 0); std::vector<double> sumMSE(outputs, 0); std::vector<double> pow2sumMSE(outputs, 0); std::vector<double> maxMSE(outputs, 0); std::vector<double> minMSE(outputs, 0); for(int i=0; i<outputs; ++i) { double nmse = (*firstIndivFitness)[i].nmse; double mse = (*firstIndivFitness)[i].mse; sumNMSE[i] = nmse; pow2sumNMSE[i] = pow2Of<double>(nmse); maxNMSE[i] = nmse; minNMSE[i] = nmse; sumMSE[i] = mse; pow2sumMSE[i] = pow2Of<double>(mse); maxMSE[i] = mse; minMSE[i] = mse; } unsigned int lMaxDepth = gpDeme[0]->getMaxTreeDepth(); unsigned int lMinDepth = lMaxDepth; double lSumDepth = (double)lMaxDepth; double lPow2SumDepth = pow2Of<double>(lSumDepth); unsigned int lMaxSize = gpDeme[0]->getTotalNodes(); unsigned int lMinSize = lMaxSize; double lSumSize = (double)lMaxSize; double lPow2SumSize = pow2Of<double>(lSumSize); unsigned indivs = 0; for(unsigned int i=1; i<ioDeme.size(); i++) { const FitnessNMSE::Handle indivFitness = castHandleT<FitnessNMSE>(ioDeme[i]->getFitness()); double tNmse = indivFitness->getNMSE(); //cout << endl << i << "\t" << tNmse << "\t" << indivFitness->size(); if(tNmse != tNmse || tNmse == numeric_limits<double>::infinity()) { continue; } ++indivs; sum += tNmse; pow2sum += pow2Of<double>(tNmse); max = maxOf<double>(max, tNmse); min = minOf<double>(min, tNmse); for(int j=0; j<outputs; ++j) { double nmse = (*indivFitness)[j].nmse; double mse = (*indivFitness)[j].mse; sumNMSE[j] += nmse; pow2sumNMSE[j] += pow2Of<double>(nmse); maxNMSE[j] = maxOf<double>(maxNMSE[j], nmse); minNMSE[j] = minOf<double>(minNMSE[j], nmse); sumMSE[j] += mse; pow2sumMSE[j] += pow2Of<double>(mse); maxMSE[j] = maxOf<double>(maxMSE[j], mse); minMSE[j] = minOf<double>(minMSE[j], mse); } unsigned int lTmpDepth = gpDeme[i]->getMaxTreeDepth(); lSumDepth += (double)lTmpDepth; lPow2SumDepth += pow2Of<double>((double)lTmpDepth); lMaxDepth = maxOf(lMaxDepth, lTmpDepth); lMinDepth = minOf(lMinDepth, lTmpDepth); unsigned int lTmpSize = gpDeme[i]->getTotalNodes(); lSumSize += (double)lTmpSize; lPow2SumSize += pow2Of<double>((double)lTmpSize); lMaxSize = maxOf(lMaxSize, lTmpSize); lMinSize = minOf(lMinSize, lTmpSize); } float lDepthStdError = (float)(lPow2SumDepth - (pow2Of<double>(lSumDepth) / indivs)) / (indivs - 1); lDepthStdError = sqrt(lDepthStdError); float lSizeStdError = (float)(lPow2SumSize - (pow2Of<double>(lSumSize) / indivs)) / (indivs - 1); lSizeStdError = sqrt(lSizeStdError); outStats.setGenerationValues(Beagle::string("deme")+uint2str(ioContext.getDemeIndex()+1), ioContext.getGeneration(), ioDeme.size(), true); outStats.resize(3+outputs*2); outStats[0].mId = "NMSE"; outStats[0].mAvg = sum / indivs; outStats[0].mStd = sqrt((pow2sum - (pow2Of<double>(sum)/indivs)) / (indivs-1)); outStats[0].mMax = max; outStats[0].mMin = min; outStats[1].mId = "treedepth"; outStats[1].mAvg = (float)(lSumDepth / indivs); outStats[1].mStd = lDepthStdError; outStats[1].mMax = (float)lMaxDepth; outStats[1].mMin = (float)lMinDepth; outStats[2].mId = "treesize"; outStats[2].mAvg = (float)(lSumSize / indivs); outStats[2].mStd = lSizeStdError; outStats[2].mMax = (float)lMaxSize; outStats[2].mMin = (float)lMinSize; for(int j=0; j<outputs; ++j) { int nr = 3 + j*2; outStats[nr].mId = "y" + int2str(j) + "-NMSE"; outStats[nr].mAvg = sumNMSE[j] / indivs; outStats[nr].mStd = sqrt((pow2sumNMSE[j] - (pow2Of<double>(sumNMSE[j])/indivs)) / (indivs-1)); outStats[nr].mMax = maxNMSE[j]; outStats[nr].mMin = minNMSE[j]; ++nr; outStats[nr].mId = "y" + int2str(j) + "-MSE"; outStats[nr].mAvg = sumMSE[j] / indivs; outStats[nr].mStd = sqrt((pow2sumMSE[j] - (pow2Of<double>(sumMSE[j])/indivs)) / (indivs-1)); outStats[nr].mMax = maxMSE[j]; outStats[nr].mMin = minMSE[j]; } Beagle_StackTraceEndM("void SinsGP::StatsCalcFitnessNMSEOp::calculateStatsDeme(Beagle::Stats& outStats, Beagle::Deme& ioDeme, Beagle::Context& ioContext) const"); }
void Beagle::MPI::EvaluationOp::distributeDemeEvaluation(Deme& ioDeme, Context& ioContext) { try{ std::vector<int> lProcess(mProcessSize, -1); lProcess[0] = -2; //Master should not be pick int lCurrentIndividual = 0; std::ostringstream lStreamOut; PACC::XML::Streamer lXMLStream(lStreamOut); //char lSizeMessage[256]; int lMessageSize; MPI_Status lStatus; int lFlag; unsigned int lSource = 1; unsigned int lProcessIdx = 0; unsigned int lRecvIndividualIdx = 0; unsigned int lNbReceived = 0; unsigned int lNbSent = 0; bool lAllSent = false; while( (lNbReceived < lNbSent) || !lAllSent ) { if(!lAllSent) { lProcessIdx = find(lProcess, -1, 0, lProcess.size()); if( lProcessIdx != lProcess.size() ) { if((ioDeme[lCurrentIndividual]->getFitness() == NULL) || (ioDeme[lCurrentIndividual]->getFitness()->isValid() == false)) { //There is a process idle Beagle_LogVerboseM( ioContext.getSystem().getLogger(), "evaluation", "Beagle::MPIEvaluationOp", std::string("Evaluating the fitness of the ")+uint2ordinal(lCurrentIndividual+1)+ " individual" ); ioContext.setIndividualIndex(lCurrentIndividual); ioContext.setIndividualHandle(ioDeme[lCurrentIndividual]); //Send the individual to be evaluated Beagle_LogTraceM( ioContext.getSystem().getLogger(), "evaluation", "Beagle::MPIEvaluationOp", std::string("Sending the ") + uint2ordinal(lCurrentIndividual+1) + std::string(" individual to ")+ uint2ordinal(lProcessIdx) + std::string(" evaluator") ); lStreamOut.str(""); ioDeme[lCurrentIndividual]->write(lXMLStream); lMessageSize = lStreamOut.str().size()+1; MPI_Send(&lMessageSize, 1, MPI_INT, lProcessIdx, eMessageSize, MPI_COMM_WORLD); MPI_Send(const_cast<char*>(lStreamOut.str().data()), lMessageSize, MPI_CHAR, lProcessIdx, eIndividual, MPI_COMM_WORLD); //std::cout << "Sending individual : " << lStreamOut.str().data() << std::endl; unsigned int lGeneration = ioContext.getGeneration(); MPI_Send(&lGeneration, 1, MPI_INT, lProcessIdx, eIndividual, MPI_COMM_WORLD); lProcess[lProcessIdx] = lCurrentIndividual; ++lNbSent; } ++lCurrentIndividual; if(lCurrentIndividual >= ioDeme.size()) { lAllSent = true; } } } //Look if any cruncher sent a fitness back MPI_Iprobe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &lFlag, &lStatus); if (lFlag) { //Receive the evaluated fitness lSource = lStatus.MPI_SOURCE; MPI_Recv(&lMessageSize, 1, MPI_INT, lSource, eMessageSize, MPI_COMM_WORLD, &lStatus); char *lMessage = new char[lMessageSize]; MPI_Recv(lMessage, lMessageSize, MPI_CHAR, lSource, eFitness, MPI_COMM_WORLD, &lStatus); lRecvIndividualIdx = lProcess[lSource]; lProcess[lSource] = -1; ++lNbReceived; Beagle_LogTraceM( ioContext.getSystem().getLogger(), "evaluation", "Beagle::MPIEvaluationOp", std::string("Receiving the fitness of the ") + uint2ordinal(lRecvIndividualIdx+1) + std::string(" individual from ")+uint2ordinal(lSource) + std::string(" evaluator") ); //Read the received fitness std::istringstream lStreamIn(lMessage); PACC::XML::Document lXMLParser; lXMLParser.parse(lStreamIn); Fitness::Handle lFitness = castHandleT<Fitness>(ioDeme[lRecvIndividualIdx]->getFitnessAlloc()->allocate()); PACC::XML::ConstIterator lFitnessRootNode = lXMLParser.getFirstRoot(); lFitness->read(lFitnessRootNode); //Free message space delete [] lMessage; //Assign the fitness ioDeme[lRecvIndividualIdx]->setFitness(lFitness); ioDeme[lRecvIndividualIdx]->getFitness()->setValid(); //Update stats ioContext.setProcessedDeme(ioContext.getProcessedDeme()+1); ioContext.setTotalProcessedDeme(ioContext.getTotalProcessedDeme()+1); ioContext.setProcessedVivarium(ioContext.getProcessedVivarium()+1); ioContext.setTotalProcessedVivarium(ioContext.getTotalProcessedVivarium()+1); Beagle_LogDebugM( ioContext.getSystem().getLogger(), "evaluation", "Beagle::MPIEvaluationOp", std::string("Received fitness of individual: ")+ ioDeme[lRecvIndividualIdx]->serialize() ); Beagle_LogDebugM( ioContext.getSystem().getLogger(), "evaluation", "Beagle::MPIEvaluationOp", std::string("The individual\'s fitness is: ")+ ioDeme[lRecvIndividualIdx]->getFitness()->serialize() ); } } } catch(Exception& inException) { std::cerr << "Exception catched in evolver:" << std::endl << std::flush; std::cerr << inException.what() << std::endl << std::flush; exit(1); } catch(std::exception& inException) { std::cerr << "Standard exception catched in evolver:" << std::endl << std::flush; std::cerr << inException.what() << std::endl << std::flush; exit(1); } }