コード例 #1
0
ファイル: GenerationalOp.cpp プロジェクト: falcong/beagle-1
/*!
 *  \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();
}
コード例 #2
0
ファイル: TermMaxFitnessOp.cpp プロジェクト: AngelGate/beagle
/*!
 *  \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);
	}
}
コード例 #4
0
/*!
 *  \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)");
}
コード例 #5
0
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;
}
コード例 #6
0
ファイル: InitializationOp.cpp プロジェクト: AngelGate/beagle
/*!
 *  \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();
}
コード例 #7
0
/*!
 *  \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();
}
コード例 #8
0
/*!
 *  \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)");
}
コード例 #9
0
/*!
 *  \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();
}
コード例 #10
0
/*!
 *  \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)");
}
コード例 #11
0
ファイル: NPGA2Op.cpp プロジェクト: AngelGate/beagle
/*!
 *  \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();
}
コード例 #12
0
ファイル: InitializationOp.cpp プロジェクト: AngelGate/beagle
/*!
 *  \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();
}
コード例 #13
0
ファイル: RecombinationOp.cpp プロジェクト: AngelGate/beagle
/*!
 *  \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();
}
コード例 #14
0
/*!
 *  \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();
}
コード例 #15
0
/*!
 *  \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();
}
コード例 #16
0
/*!
 *  \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();
}
コード例 #17
0
ファイル: NSGA2Op.cpp プロジェクト: GhostGambler/beagle
/*!
 *  \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();
}
コード例 #18
0
ファイル: CrossoverOp.cpp プロジェクト: AngelGate/beagle
/*!
 *  \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();
}
コード例 #19
0
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);
	}
}