Exemplo n.º 1
0
/*!
 *  \brief Assign a new Id to the individual.
 */
inline void Beagle::History::allocateNewID(Beagle::Individual& ioIndividual)
{
	Beagle_StackTraceBeginM();
	HistoryID::Handle lHID = castHandleT<HistoryID>(ioIndividual.getMember("HistoryID"));
	if(lHID == NULL) ioIndividual.addMember(new HistoryID(mTracesCount++, 0));
	else lHID->setID(mTracesCount++);
	Beagle_StackTraceEndM();
}
Exemplo n.º 2
0
/*!
 *  \brief Assign a new Id to the individual if it has a none.
 */
inline void Beagle::History::allocateID(Beagle::Individual& ioIndividual)
{
	Beagle_StackTraceBeginM();
	if(ioIndividual.getMember("HistoryID") == NULL) {
		ioIndividual.addMember(new HistoryID(mTracesCount++, 0));
	}
	Beagle_StackTraceEndM();
}
Exemplo n.º 3
0
/*!
 *  \brief Increment the history variation number of the individual.
 */
inline void Beagle::History::incrementHistoryVar(Beagle::Individual& ioIndividual)
{
	Beagle_StackTraceBeginM();
	HistoryID::Handle lHID = castHandleT<HistoryID>(ioIndividual.getMember("HistoryID"));
	if(lHID == NULL) ioIndividual.addMember(new HistoryID(mTracesCount++, 0));
	else lHID->incrementVar();
	Beagle_StackTraceEndM();
}
/*!
 *  \brief Mutate an ES individual.
 *  \param ioIndividual ES individual to mutate.
 *  \param ioContext Context of the evolution.
 *  \return True as individual are always mutated.
 */
bool GA::MutationESVecOp::mutate(Beagle::Individual& ioIndividual, Context& ioContext)
{
	Beagle_StackTraceBeginM();
	Beagle_ValidateParameterM(mMinStrategy->getWrappedValue()>=0.0,mMinStrategyName,"<0");

	Beagle_LogVerboseM(
	    ioContext.getSystem().getLogger(),
	    "mutation", "Beagle::GA::MutationESVecOp",
	    std::string("Applying evolution strategy mutation to an individual")
	);

	for(unsigned int i=0; i<ioIndividual.size(); i++) {
		GA::ESVector::Handle lVector = castHandleT<GA::ESVector>(ioIndividual[i]);
		Beagle_LogVerboseM(
		    ioContext.getSystem().getLogger(),
		    "mutation", "Beagle::GA::MutationESVecOp",
		    std::string("Mutating the ")+uint2ordinal(i+1)+" ES vector"
		);
		Beagle_LogObjectDebugM(
		    ioContext.getSystem().getLogger(),
		    "mutation", "Beagle::GA::MutationESVecOp",
		    *lVector
		);

		const double lT = 1.0 / std::sqrt(2.0 * std::sqrt(double(lVector->size())));
		const double lTPrime = 1.0 / std::sqrt(2.0 * lVector->size());
		const double lN = ioContext.getSystem().getRandomizer().rollGaussian(0.0, 1.0);
		const double lMinStrategy = mMinStrategy->getWrappedValue();
		for(unsigned int j=0; j<lVector->size(); j++) {
			const double lMaxVal = j<mMaxValue->size() ? (*mMaxValue)[j] : mMaxValue->back();
			const double lMinVal = j<mMinValue->size() ? (*mMinValue)[j] : mMinValue->back();
			const double lNi = ioContext.getSystem().getRandomizer().rollGaussian(0.0, 1.0);

			(*lVector)[j].mStrategy *= std::exp((lTPrime * lN) + (lT * lNi));
			if((*lVector)[j].mStrategy < lMinStrategy) (*lVector)[j].mStrategy = lMinStrategy;
			(*lVector)[j].mValue += (*lVector)[j].mStrategy * lNi;
			if((*lVector)[j].mValue > lMaxVal) (*lVector)[j].mValue = lMaxVal;
			if((*lVector)[j].mValue < lMinVal) (*lVector)[j].mValue = lMinVal;

			Beagle_LogDebugM(
			    ioContext.getSystem().getLogger(),
			    "mutation", "Beagle::GA::MutationESVecOp",
			    std::string("ES mutating by adding ")+dbl2str((*lVector)[j].mStrategy * lNi)+
			    std::string(" to the value and multiplying the strategy by ")+
			    dbl2str(std::exp((lTPrime * lN) + (lT * lNi)))+
			    std::string(" to mutate the pair ")+uint2str(j)+
			    std::string(" of the ES vector")
			);
		}

		Beagle_LogObjectDebugM(
		    ioContext.getSystem().getLogger(),
		    "mutation", "Beagle::GA::MutationESVecOp",
		    *lVector
		);
	}
	return true;
	Beagle_StackTraceEndM("bool GA::MutationESVecOp::mutate(Beagle::Individual& ioIndividual, Context& ioContext)");
}
/*!
 *  \brief Uniformly mutate an integer vector GA individual.
 *  \param ioIndividual GA individual to mutate.
 *  \param ioContext Context of the evolution.
 *  \return True if the individual is effectively mutated, false if not.
 */
bool GA::MutationUniformIntVecOp::mutate(Beagle::Individual& ioIndividual, Context& ioContext)
{
	Beagle_StackTraceBeginM();
	Beagle_ValidateParameterM(mIntMutateProba->getWrappedValue()>=0.0, mIntMutatePbName, "<0");

	bool lMutated = false;
	Beagle_LogVerboseM(
	    ioContext.getSystem().getLogger(),
	    "mutation", "Beagle::GA::MutationUniformIntVecOp",
	    std::string("Integer uniform mutation probability is: ")+
	    dbl2str(mIntMutateProba->getWrappedValue())
	);

	for(unsigned int i=0; i<ioIndividual.size(); i++) {
		GA::IntegerVector::Handle lIV = castHandleT<GA::IntegerVector>(ioIndividual[i]);
		Beagle_LogVerboseM(
		    ioContext.getSystem().getLogger(),
		    "mutation", "Beagle::GA::MutationUniformIntVecOp",
		    std::string("Uniformly mutating the ")+uint2ordinal(i+1)+" integer vector"
		);
		Beagle_LogObjectDebugM(
		    ioContext.getSystem().getLogger(),
		    "mutation", "Beagle::GA::MutationUniformIntVecOp",
		    *lIV
		);
		for(unsigned int j=0; j<lIV->size(); j++) {
			double lRolledPb = ioContext.getSystem().getRandomizer().rollUniform();
			if(lRolledPb <= mIntMutateProba->getWrappedValue()) {
				const int lMaxVal = j<mMaxValue->size() ? (*mMaxValue)[j] : mMaxValue->back();
				const int lMinVal = j<mMinValue->size() ? (*mMinValue)[j] : mMinValue->back();
				Beagle_AssertM(lMaxVal >= lMinVal);
				const int lRandVal = (int)ioContext.getSystem().getRandomizer().rollInteger(0,lMaxVal-lMinVal);
				(*lIV)[j] = (lRandVal+lMinVal);
				lMutated = true;
			}
		}
		if(lMutated) {
			Beagle_LogVerboseM(
			    ioContext.getSystem().getLogger(),
			    "mutation", "Beagle::GA::MutationUniformIntVecOp",
			    std::string("The integer vector has been uniformly mutated")
			);
			Beagle_LogObjectDebugM(
			    ioContext.getSystem().getLogger(),
			    "mutation", "Beagle::GA::MutationUniformIntVecOp",
			    *lIV
			);
		} else {
			Beagle_LogVerboseM(
			    ioContext.getSystem().getLogger(),
			    "mutation", "Beagle::GA::MutationUniformIntVecOp",
			    std::string("The integer vector has not been mutated")
			);
		}
	}
	return lMutated;
	Beagle_StackTraceEndM("bool GA::MutationUniformIntVecOp::mutate(Beagle::Individual& ioIndividual, Context& ioContext)");
}
/*!
 *  \brief Initialize ES individual with initial strategy parameter.
 *  \param outIndividual Individual to initialize.
 *  \param ioContext Evolution context.
 *
 *  Size of ES individual is given by integer vector "es.init.vectorsize". Initial strategy
 *  parameter value of ES pair is given by parameter "es.init.strategy". Initial value of ES pair
 *  is given using random numbers following a Gaussian distribution of zero mean and standard
 *  deviation equal to initial strategy parameter value.
 */
void GA::InitQRESVecOp::initIndividual(Beagle::Individual& outIndividual, Context& ioContext)
{
	Beagle_StackTraceBeginM();
#ifndef BEAGLE_NDEBUG
	if(mESVectorSize->getWrappedValue() == 0) {
		std::string lMessage = "GA::InitQRESVecOp::initIndividual: ";
		lMessage += "ES vector size parameter is zero; ";
		lMessage += "could not initialize the individuals!";
		throw Beagle_RunTimeExceptionM(lMessage);
	}
#endif // BEAGLE_NDEBUG

	const Factory& lFactory = ioContext.getSystem().getFactory();
	GA::ESVector::Alloc::Handle lESVectorAlloc =
		castHandleT<GA::ESVector::Alloc>(lFactory.getConceptAllocator("Genotype"));
	GA::ESVector::Handle lESVector = castHandleT<GA::ESVector>(lESVectorAlloc->allocate());
	lESVector->resize(mESVectorSize->getWrappedValue());
	outIndividual.clear();
	outIndividual.push_back(lESVector);
	Vector lQRValues(mESVectorSize->getWrappedValue()+1);
	QuasiRandom::Handle lQRComponent =
	    castHandleT<QuasiRandom>(ioContext.getSystem().getComponent("QuasiRandom"));
	lQRComponent->getUniformVector(lQRValues);
	Beagle_AssertM((mESVectorSize->getWrappedValue()+1) == lQRValues.size());
	const double lInitStrategy = mInitStrategyValue->getWrappedValue();
	for(unsigned int j=0; j<lESVector->size(); ++j) {
		const double lMaxVal = j<mMaxValue->size() ? (*mMaxValue)[j] : mMaxValue->back();
		const double lMinVal = j<mMinValue->size() ? (*mMinValue)[j] : mMinValue->back();
		(*lESVector)[j].mValue = (lQRValues[j] * lInitStrategy);
		if((*lESVector)[j].mValue > lMaxVal) (*lESVector)[j].mValue = lMaxVal;
		if((*lESVector)[j].mValue < lMinVal) (*lESVector)[j].mValue = lMinVal;
		(*lESVector)[j].mStrategy = lInitStrategy;
	}
	Beagle_LogDebugM(
	    ioContext.getSystem().getLogger(),
	    "initialization", "Beagle::GA::InitQRESVecOp",
	    "ES vector is initialized as"
	);
	Beagle_LogObjectDebugM(
	    ioContext.getSystem().getLogger(),
	    "initialization", "Beagle::GA::InitQRESVecOp",
	    *lESVector
	);
	Beagle_StackTraceEndM("void GA::InitQRESVecOp::initIndividual(Beagle::Individual& outIndividual, Context& ioContext)");
}
Exemplo n.º 7
0
/*!
 *  \brief Initialize real-valued individual with derandomized Gaussian values.
 *  \param outIndividual Individual to initialize.
 *  \param ioContext Evolution context.
 */
void FltVec::InitGaussianQROp::initIndividual(Beagle::Individual& outIndividual, Context& ioContext)
{
    Beagle_StackTraceBeginM();
#ifndef BEAGLE_NDEBUG
    if(mFloatVectorSize->getWrappedValue() == 0) {
        string lMessage = "FltVec::InitGaussianQROp::initIndividual: ";
        lMessage += "float vector size parameter is zero; ";
        lMessage += "could not initialize the individuals!";
        throw Beagle_RunTimeExceptionM(lMessage);
    }
#endif // BEAGLE_NDEBUG
    const Factory& lFactory = ioContext.getSystem().getFactory();
    FltVec::FloatVector::Alloc::Handle lVectorAlloc =
        castHandleT<FltVec::FloatVector::Alloc>(lFactory.getConceptAllocator("Genotype"));
    FltVec::FloatVector::Handle lVector =
        castHandleT<FltVec::FloatVector>(lVectorAlloc->allocate());
    lVector->resize(mFloatVectorSize->getWrappedValue());
    outIndividual.clear();
    outIndividual.push_back(lVector);
    QuasiRandom::Handle lQRComponent =
        castHandleT<QuasiRandom>(ioContext.getSystem().getComponent("QuasiRandom"));
    Vector lQRValues(lVector->size());
    lQRComponent->getGaussianVector(lQRValues);
    Beagle_AssertM(mFloatVectorSize->getWrappedValue() == lQRValues.size());
    for(unsigned int j=0; j<lVector->size(); ++j) {
        const double lMaxVal = j<mMaxInitValue->size() ? (*mMaxInitValue)[j] : mMaxInitValue->back();
        const double lMinVal = j<mMinInitValue->size() ? (*mMinInitValue)[j] : mMinInitValue->back();
        const double lIncVal = j<mIncValue->size() ? (*mIncValue)[j] : mIncValue->back();
        const double lMean   = j<mMean->size() ? (*mMean)[j] : mMean->back();
        const double lStdev  = j<mStdev->size() ? (*mStdev)[j] : mStdev->back();
        (*lVector)[j] = (lQRValues[j] * lStdev) + lMean;
        if((*lVector)[j] > lMaxVal) (*lVector)[j] = lMaxVal;
        if((*lVector)[j] < lMinVal) (*lVector)[j] = lMinVal;
        if(std::fabs(lIncVal)>1e-12) {
            (*lVector)[j] = lIncVal * round((*lVector)[j] / lIncVal);
            if((*lVector)[j] > lMaxVal) (*lVector)[j] -= lIncVal;
            if((*lVector)[j] < lMinVal) (*lVector)[j] += lIncVal;
        }
    }
    Beagle_LogDebugM(
        ioContext.getSystem().getLogger(),
        *lVector
    );
    Beagle_StackTraceEndM();
}
/*!
 *  \brief Initialize real-valued GA individual with numbers uniformly distributed in a given range.
 *  \param outIndividual Individual to initialize.
 *  \param ioContext Evolution context.
 */
void GA::InitFltVecOp::initIndividual(Beagle::Individual& outIndividual, Context& ioContext)
{
	Beagle_StackTraceBeginM();
#ifndef BEAGLE_NDEBUG
	if(mFloatVectorSize->getWrappedValue() == 0) {
		string lMessage = "GA::InitFltVecOp::initIndividual: ";
		lMessage += "float vector size parameter is zero; ";
		lMessage += "could not initialize the individuals!";
		throw Beagle_RunTimeExceptionM(lMessage);
	}
#endif // BEAGLE_NDEBUG
	const Factory& lFactory = ioContext.getSystem().getFactory();
	GA::FloatVector::Alloc::Handle lFloatVectorAlloc =
		castHandleT<GA::FloatVector::Alloc>(lFactory.getConceptAllocator("Genotype"));
	GA::FloatVector::Handle lFloatVector =
		castHandleT<GA::FloatVector>(lFloatVectorAlloc->allocate());
	lFloatVector->resize(mFloatVectorSize->getWrappedValue());
	outIndividual.clear();
	outIndividual.push_back(lFloatVector);
	for(unsigned int j=0; j<lFloatVector->size(); ++j) {
		const double lMaxVal = j<mMaxInitValue->size() ? (*mMaxInitValue)[j] : mMaxInitValue->back();
		const double lMinVal = j<mMinInitValue->size() ? (*mMinInitValue)[j] : mMinInitValue->back();
		const double lIncVal = j<mIncValue->size() ? (*mIncValue)[j] : mIncValue->back();
		(*lFloatVector)[j] = ioContext.getSystem().getRandomizer().rollUniform(lMinVal,lMaxVal);
		if(std::fabs(lIncVal)>1e-12) {
			(*lFloatVector)[j] = lIncVal * round((*lFloatVector)[j] / lIncVal);
			if((*lFloatVector)[j] > lMaxVal) (*lFloatVector)[j] = lMaxVal;
			if((*lFloatVector)[j] < lMinVal) (*lFloatVector)[j] = lMinVal;
		}
	}
	Beagle_LogDebugM(
	    ioContext.getSystem().getLogger(),
	    "initialization",
	    "Beagle::GA::InitFltVecOp",
	    string("Float vector initialized as")
	);
	Beagle_LogObjectDebugM(
	    ioContext.getSystem().getLogger(),
	    "initialization",
	    "Beagle::GA::InitFltVecOp",
	    *lFloatVector
	);
	Beagle_StackTraceEndM("void GA::InitFltVecOp::initIndividual(Beagle::Individual& outIndividual, Context& ioContext)");
}
Exemplo n.º 9
0
/*!
 *  \brief Mutate a linear GP individual.
 *  \param ioIndividual Linear GP individual to mutate.
 *  \param ioContext Context of the evolution.
 *  \return True if the individual is effectively mutated, false if not.
 */
bool LinGP::MutationOp::mutate(Beagle::Individual& ioIndividual, Beagle::Context& ioContext)
{
	Beagle_ValidateParameterM(mInstructMutateProba->getWrappedValue()>=0.0,
	                          mInstructMutatePbName, "<0");
	bool lMutated = false;
	Beagle_LogVerboseM(
	    ioContext.getSystem().getLogger(),
	    std::string("Linear GP mutation probability is: ")+
	    dbl2str(mInstructMutateProba->getWrappedValue())
	);

	LinGP::Context& lLinGPContext = castObjectT<LinGP::Context&>(ioContext);
	LinGP::InstructionSuperSet::Handle lInsSS =
	    castHandleT<LinGP::InstructionSuperSet>(lLinGPContext.getSystem().getComponent("LinGP-InstructionSuperSet"));

	for(unsigned int i=0; i<ioIndividual.size(); i++) {
		LinGP::Program::Handle lProgram = castHandleT<LinGP::Program>(ioIndividual[i]);
		Beagle_LogVerboseM(
		    ioContext.getSystem().getLogger(),
		    std::string("Mutating the ")+uint2ordinal(i+1)+" program"
		);
		Beagle_LogDebugM(
		    ioContext.getSystem().getLogger(),
		    *lProgram
		);
		for(unsigned int j=0; j<lProgram->size(); j++) {
			double lRolledPb = ioContext.getSystem().getRandomizer().rollUniform();
			if(lRolledPb <= mInstructMutateProba->getWrappedValue()) {
				(*lProgram)[j] =
				    lInsSS->getInstructionSets()[i]->selectRandomInstruction(lLinGPContext.getSystem())->giveReference(lLinGPContext);
				lMutated = true;
			}
		}
		if(lMutated) {
			Beagle_LogVerboseM(
			    ioContext.getSystem().getLogger(),
			    std::string("The program has been mutated")
			);
			Beagle_LogDebugM(
			    ioContext.getSystem().getLogger(),
			    *lProgram
			);
		} else {
			Beagle_LogVerboseM(
			    ioContext.getSystem().getLogger(),
			    std::string("The program has not been mutated")
			);
		}
	}
	return lMutated;
}
/*!
 *  \brief Initialize integer-valued GA individual with numbers uniformly distributed in a given range.
 *  \param outIndividual Individual to initialize.
 *  \param ioContext Evolution context.
 */
void GA::InitIntVecOp::initIndividual(Beagle::Individual& outIndividual, Context& ioContext)
{
	Beagle_StackTraceBeginM();
#ifndef BEAGLE_NDEBUG
	if(mIntVectorSize->getWrappedValue() == 0) {
		string lMessage = "GA::InitIntVecOp::initIndividual: ";
		lMessage += "integer vector size parameter is zero; ";
		lMessage += "could not initialize the individuals!";
		throw Beagle_RunTimeExceptionM(lMessage);
	}
#endif // BEAGLE_NDEBUG
	const Factory& lFactory = ioContext.getSystem().getFactory();
	GA::IntegerVector::Alloc::Handle lIntegerVectorAlloc =
		castHandleT<GA::IntegerVector::Alloc>(lFactory.getConceptAllocator("Genotype"));
	GA::IntegerVector::Handle lIntegerVector = castHandleT<GA::IntegerVector>(lIntegerVectorAlloc->allocate());
	lIntegerVector->resize(mIntVectorSize->getWrappedValue());
	outIndividual.clear();
	outIndividual.push_back(lIntegerVector);
	for(unsigned int j=0; j<lIntegerVector->size(); ++j) {
		const int lMaxVal = j<mMaxInitValue->size() ? (*mMaxInitValue)[j] : mMaxInitValue->back();
		const int lMinVal = j<mMinInitValue->size() ? (*mMinInitValue)[j] : mMinInitValue->back();
		Beagle_AssertM(lMaxVal >= lMinVal);
		const int lRandVal = (int)ioContext.getSystem().getRandomizer().rollInteger(0,lMaxVal-lMinVal);
		(*lIntegerVector)[j] = (lRandVal+lMinVal);
	}
	Beagle_LogDebugM(
	    ioContext.getSystem().getLogger(),
	    "initialization", "Beagle::GA::InitIntVecOp",
	    "Integer vector initialized as"
	);
	Beagle_LogObjectDebugM(
	    ioContext.getSystem().getLogger(),
	    "initialization",
	    "Beagle::GA::InitIntVecOp",
	    *lIntegerVector
	);
	Beagle_StackTraceEndM("void GA::InitIntVecOp::initIndividual(Beagle::Individual& outIndividual, Context& ioContext)");
}
Exemplo n.º 11
0
/*!
 *  \brief Bit flip mutate a bit string individual.
 *  \param ioIndividual Individual to mutate.
 *  \param ioContext Context of the evolution.
 *  \return True if the individual is effectively mutated, false if not.
 */
bool BitStr::MutationFlipBitOp::mutate(Beagle::Individual& ioIndividual, Context& ioContext)
{
	Beagle_StackTraceBeginM();
	Beagle_ValidateParameterM(mBitMutateProba->getWrappedValue()>=0.0, mBitMutatePbName, "<0");
	bool lMutated = false;
	Beagle_LogVerboseM(
	    ioContext.getSystem().getLogger(),
	    std::string("Bit flip mutation probability is: ")+dbl2str(mBitMutateProba->getWrappedValue())
	);

	for(unsigned int i=0; i<ioIndividual.size(); i++) {
		BitStr::BitString::Handle lBS = castHandleT<BitStr::BitString>(ioIndividual[i]);
		Beagle_LogVerboseM(
		    ioContext.getSystem().getLogger(),
		    std::string("Flip mutating the ")+uint2ordinal(i+1)+" bitstring"
		);
		Beagle_LogDebugM(ioContext.getSystem().getLogger(), *lBS);
		for(unsigned int j=0; j<lBS->size(); j++) {
			double lRolledPb = ioContext.getSystem().getRandomizer().rollUniform();
			if(lRolledPb <= mBitMutateProba->getWrappedValue()) {
				(*lBS)[j] = !(*lBS)[j];
				lMutated = true;
			}
		}
		if(lMutated) {
			Beagle_LogVerboseM(
			    ioContext.getSystem().getLogger(),
			    std::string("The bitstring has been flip mutated")
			);
			Beagle_LogDebugM(ioContext.getSystem().getLogger(), *lBS);
		} else {
			Beagle_LogVerboseM(
			    ioContext.getSystem().getLogger(),
			    std::string("The bitstring has not been mutated")
			);
		}
	}
	return lMutated;
	Beagle_StackTraceEndM();
}
Exemplo n.º 12
0
/*!
 *  \brief Mate two GP individuals for a constrained tree crossover.
 *  \param ioIndiv1   First individual to mate.
 *  \param ioContext1 Evolutionary context of the first individual.
 *  \param ioIndiv2   Second individual to mate.
 *  \param ioContext2 Evolutionary context of the second individual.
 *  \return True if the individuals are effectively mated, false if not.
 */
bool STGP::CrossoverConstrainedOp::mate(Beagle::Individual& ioIndiv1, Beagle::Context& ioContext1,
                                      Beagle::Individual& ioIndiv2, Beagle::Context& ioContext2)
{
	Beagle_StackTraceBeginM();
	// Initial parameters checks
	Beagle_AssertM(ioIndiv1.size() > 0);
	//Beagle_AssertM(ioIndiv1.size() == ioIndiv2.size());
	Beagle_ValidateParameterM(mNumberAttempts->getWrappedValue()>0,"gp.try",">0");

	// Cast method arguments.
	GP::Individual& lIndiv1   = castObjectT<GP::Individual&>(ioIndiv1);
	GP::Individual& lIndiv2   = castObjectT<GP::Individual&>(ioIndiv2);
	GP::Context&    lContext1 = castObjectT<GP::Context&>(ioContext1);
	GP::Context&    lContext2 = castObjectT<GP::Context&>(ioContext2);

	// Get parameters in local values, with the total number of nodes of an individual.
	bool             lMatingDone     = false;
	float            lDistrProba     = mDistributionProba->getWrappedValue();
	unsigned int     lMaxTreeDepth   = mMaxTreeDepth->getWrappedValue();
	GP::Tree::Handle lOldTreeHandle1 = lContext1.getGenotypeHandle();
	unsigned int     lOldTreeIndex1  = lContext1.getGenotypeIndex();
	GP::Tree::Handle lOldTreeHandle2 = lContext2.getGenotypeHandle();
	unsigned int     lOldTreeIndex2  = lContext2.getGenotypeIndex();
	unsigned int     lSizeIndiv1     = 0;
	for(unsigned int i=0; i<lIndiv1.size(); i++) lSizeIndiv1 += lIndiv1[i]->size();

	Beagle_LogDebugM(
	    ioContext1.getSystem().getLogger(),
	    "Individuals to mate (before constrained GP crossover)"
	);
	Beagle_LogDebugM(
	    ioContext1.getSystem().getLogger(),
	    lIndiv1
	);
	Beagle_LogDebugM(
	    ioContext1.getSystem().getLogger(),
	    lIndiv2
	);

	// Crossover loop. Try the given number of attempts to mate two individuals.
	for(unsigned int lAttempt=0; lAttempt < mNumberAttempts->getWrappedValue(); ++lAttempt) {

		// Choose a node in all the individual node.
		unsigned int lChoosenNode1 =
		    lContext1.getSystem().getRandomizer().rollInteger(0, lSizeIndiv1-1);

		// Get the tree in which the choosen node is. Change the global node index to the tree's index.
		unsigned int lChoosenTree1 = 0;
		for(; lChoosenTree1<lIndiv1.size(); lChoosenTree1++) {
			if(lChoosenNode1 < lIndiv1[lChoosenTree1]->size()) break;
			Beagle_AssertM(lChoosenNode1 >= lIndiv1[lChoosenTree1]->size());
			lChoosenNode1 -= lIndiv1[lChoosenTree1]->size();
		}
		Beagle_AssertM(lChoosenTree1 < lIndiv1.size());

		// Choose a type of node (branch or leaf) following the distribution probability and change the
		// node for another node of the same tree if the types mismatch.
		GP::Tree& lTree1 = *lIndiv1[lChoosenTree1];
		const unsigned int lPrimitiveSetIndex1 = lTree1.getPrimitiveSetIndex();
		if(lTree1.size() > 1) {
			bool lTypeNode1 =
			    (lContext1.getSystem().getRandomizer().rollUniform(0.0, 1.0) < lDistrProba);
			while((lTree1[lChoosenNode1].mPrimitive->getNumberArguments() != 0) != lTypeNode1) {
				lChoosenNode1 = lContext1.getSystem().getRandomizer().rollInteger(0, lTree1.size()-1);
			}
		}

		// Choose type of node (branch or leaf) for the second node.
		const bool lTypeNode2 =
		    (lContext2.getSystem().getRandomizer().rollUniform(0.0, 1.0) < lDistrProba);

		// Compute max depth allowable.
		lTree1.setContextToNode(lChoosenNode1, lContext1);
		const unsigned int lTmpMaxDepth1 = lMaxTreeDepth - lContext1.getCallStackSize();
		const unsigned int lTmpMaxDepth2 = lMaxTreeDepth - lTree1.getTreeDepth(lChoosenNode1);
		const unsigned int lMaxDepthTree2 = minOf(lTmpMaxDepth1, lTmpMaxDepth2);

		// Select a node in second individual for the crossover.
		unsigned int lChoosenTree2=0;
		unsigned int lChoosenNode2=0;

#ifdef BEAGLE_HAVE_RTTI
		const std::type_info* lDesiredType = lTree1[lChoosenNode1].mPrimitive->getReturnType(lContext1);
		bool lGoodSelect = selectNodeToMateWithType(lChoosenTree2,
		                   lChoosenNode2,
		                   lTypeNode2,
		                   lDesiredType,
		                   lPrimitiveSetIndex1,
		                   lMaxDepthTree2,
		                   UINT_MAX,
		                   lIndiv2,
		                   lContext2);
#else // BEAGLE_HAVE_RTTI
		bool lGoodSelect = selectNodeToMate(lChoosenTree2,
											lChoosenNode2,
											lTypeNode2,
											lPrimitiveSetIndex1,
											lMaxDepthTree2,
											UINT_MAX,
											lIndiv2,
											lContext2);
#endif // BEAGLE_HAVE_RTTI

		// Check to see that there is at least one node that can be selected
		if(lGoodSelect==false) {
			Beagle_LogVerboseM(
			    ioContext1.getSystem().getLogger(),
			    std::string("Crossover attempt failed: it seems there is no corresponding nodes in second ")+
			    std::string("individual that would meet all the constraints")
			);
			continue;
		}

		// Get reference to the tree the choosen node is in.
		Beagle_AssertM(lChoosenTree2 < lIndiv2.size());
		GP::Tree& lTree2 = *lIndiv2[lChoosenTree2];
		lTree2.setContextToNode(lChoosenNode2, lContext2);

		// Mate the trees.
		Beagle_LogVerboseM(
		    ioContext1.getSystem().getLogger(),
		    std::string("Trying to exchange the ")+uint2ordinal(lChoosenNode1+1)+
		    std::string(" node of the ")+uint2ordinal(lChoosenTree1+1)+
		    std::string(" tree of the first individual with the ")+uint2ordinal(lChoosenNode2+1)+
		    std::string(" node of the ")+uint2ordinal(lChoosenTree2+1)+
		    std::string(" tree of the second individual")
		);

		mateTrees(lTree1, lChoosenNode1, lContext1, lTree2, lChoosenNode2, lContext2);

		// If one tree is not valid, undo the crossover and do a new crossover attempt.
		lContext1.setGenotypeHandle(lIndiv1[lChoosenTree1]);
		lContext1.setGenotypeIndex(lChoosenTree1);
		lContext2.setGenotypeHandle(lIndiv2[lChoosenTree2]);
		lContext2.setGenotypeIndex(lChoosenTree2);
		if(lTree1.validateSubTree(lChoosenNode1,lContext1) &&
		        lTree2.validateSubTree(lChoosenNode2,lContext2)) {
			lMatingDone = true;
			Beagle_LogVerboseM(
			    ioContext1.getSystem().getLogger(),
			    "Constrained tree GP crossover valid"
			);
			break; // The crossover is valid.
		} else {   // Undo crossover.
			Beagle_LogVerboseM(
			    ioContext1.getSystem().getLogger(),
			    "Crossover attempt failed because one of the resulting trees was invalid"
			);
			mateTrees(lTree1, lChoosenNode1, lContext1, lTree2, lChoosenNode2, lContext2);
			continue;
		}
	}

	// Replace the contexts.
	lContext1.setGenotypeHandle(lOldTreeHandle1);
	lContext1.setGenotypeIndex(lOldTreeIndex1);
	lContext2.setGenotypeHandle(lOldTreeHandle2);
	lContext2.setGenotypeIndex(lOldTreeIndex2);

	if(lMatingDone) {
		Beagle_LogDebugM(
		    ioContext1.getSystem().getLogger(),
		    "Individuals mated (after constrained tree GP crossover)"
		);
		Beagle_LogDebugM(
		    ioContext1.getSystem().getLogger(),
		    lIndiv1
		);
		Beagle_LogDebugM(
		    ioContext1.getSystem().getLogger(),
		    lIndiv2
		);
	} else {
		Beagle_LogVerboseM(
		    ioContext1.getSystem().getLogger(),
		    "No constrained tree GP crossover done"
		);
	}

	return lMatingDone;
	Beagle_StackTraceEndM();
}
/*!
 *  \brief Evaluate the fitness of the given individual.
 *  \param inIndividual Current individual to evaluate.
 *  \param ioContext Evolutionary context.
 *  \return Handle to the fitness value of the individual.
 */
Beagle::Fitness::Handle AnalogFilterParameterEvalOp::evaluate(Beagle::Individual& inIndividual, Beagle::Context& ioContext) {
    Beagle_AssertM(inIndividual.size() == 1);

    Beagle_LogVerboseM(
        ioContext.getSystem().getLogger(),
        "evaluation", "AnalogFilterParameterEvalOp",
        std::string("Evaluating individual: ")+
        inIndividual.serialize()
    );

    BGFitness *lFitness = new BGFitness(0);
    GrowingBondGraph::Handle lBondGraph;

    GA::FloatVector::Handle lParametersVector = castHandleT<GA::FloatVector>(inIndividual[0]);

    BGContext& lBGContext = castObjectT<BGContext&>(ioContext);

    SpeciesGA& lSpecies = castObjectT<SpeciesGA&>(ioContext.getDeme());
    RepresentantGP::Handle lIndividual = castHandleT<RepresentantGP>(lSpecies.getRepresentant());

    TreeSTag::Handle lTree = castHandleT<TreeSTag>((*lIndividual)[0]);
//	lTree->assignNewParameterVector(lParametersVector, lBGContext);
    lBondGraph = lTree->getBondGraph();
    lBondGraph->assignParameters(*lParametersVector);


    lIndividual->getFitness()->setInvalid();

    Beagle_LogDebugM(
        ioContext.getSystem().getLogger(),
        "evaluation", "AnalogFilterParameterEvalOp",
        std::string("Individual after parameter assignment: ")+
        lIndividual->serialize()
    );

    try {
        vector<double> lInitial;

        //Run the individual to create the bond graph.
//		RootReturn lResult;
//
//		lBGContext.setIndividualHandle(lIndividual);
//		lIndividual->run(lResult, lBGContext);
//		lBondGraph = lBGContext.getBondGraph();
//		lTree->setBondGraph(lBondGraph);
//
//		//Set output bond
//		Bond* lOutputBond = lBondGraph->getComponents()[lResult.getValue()-1]->getPorts()[0]->getBond();
//		lBondGraph->setOutputBonds(lOutputBond, 0);

        Beagle_LogDebugM(
            ioContext.getSystem().getLogger(),
            "evaluation", "AnalogFilterParameterEvalOp",
            std::string("Evaluating bondgrap: ")+
            lBondGraph->BondGraph::serialize()
        );
        //lBondGraph->simplify();

        //Get state equations
        lBondGraph->assignCausality();
        lBondGraph->computeStateEquation();
        PACC::Matrix lA,lB,lB2,lC,lD,lD2;
        lBondGraph->getStateMatrix(lA,lB,lB2);
        lBondGraph->getOutputMatrix(lC,lD,lD2);

        lFitness->addStateMatrix(lA);
        lFitness->addStateMatrix(lB);
        lFitness->addStateMatrix(lC);
        lFitness->addStateMatrix(lD);

        //Check to see if the system is LTI
        if(lBondGraph->hasDeferentialCausality()) {
            //lFitness->setValue(ioContext.getSystem().getRandomizer().getFloat());
            lFitness->setValue(0);
            //delete lBondGraph;
            return lFitness;
        } else {
#ifndef DEBUG_NOMATLAB
            //Evalute the response in Matlab.

            // Cast the state matrix as input data
            // The mwArray::SetData is copying in column major order and the PACC::Matrix is a row major order
            // Therefore, the matrix need to be transposed.
            PACC::Matrix lAt,lBt,lCt,lDt;
            if(!lA.empty())
                lAt = lA.transpose();
            if(!lB.empty())
                lBt = lB.transpose();
            if(!lC.empty())
                lCt = lC.transpose();
            if(!lD.empty())
                lDt = lD.transpose();

            double *lValueA = new double[lAt.size()];
            std::copy(lAt.begin(), lAt.end(), lValueA);

            mwArray lArrayA(lAt.getCols(),lAt.getRows(), mxDOUBLE_CLASS, mxREAL);
            lArrayA.SetData(lValueA,lAt.size());

            double *lValueB = new double[lBt.size()];
            std::copy(lBt.begin(), lBt.end(), lValueB);
            mwArray lArrayB(lBt.getCols(),lBt.getRows(), mxDOUBLE_CLASS, mxREAL);
            lArrayB.SetData(lValueB,lBt.size());

            double *lValueC = new double[lCt.size()];
            std::copy(lCt.begin(), lCt.end(), lValueC);
            mwArray lArrayC(lCt.getCols(),lCt.getRows(), mxDOUBLE_CLASS, mxREAL);
            lArrayC.SetData(lValueC,lCt.size());

            double *lValueD = new double[lDt.size()];
            std::copy(lDt.begin(), lDt.end(), lValueD);
            mwArray lArrayD(lDt.getCols(),lDt.getRows(), mxDOUBLE_CLASS, mxREAL);
            lArrayD.SetData(lValueD,lDt.size());


            // Create output array
            mwArray loutArray;

            // Call the library function

            AnalogFilterEval(1, loutArray, lArrayA, lArrayB, lArrayC,lArrayD);

            // Extract the output
            int lNbOutput = loutArray.NumberOfElements();

            double* loutValues = new double[lNbOutput];
            loutArray.GetData(loutValues, lNbOutput);

            // Bundle the fitness
            lFitness->setValue(loutValues[0]);


            delete [] lValueA;
            delete [] lValueB;
            delete [] lValueC;
            delete [] lValueD;
            delete [] loutValues;
#else
            lFitness->setValue(ioContext.getSystem().getRandomizer().getFloat());
#endif

        }

    }
    catch (const mwException& inException)  {
        std::cerr << inException.what() << std::endl;

        PACC::Matrix lA,lB,lB2,lC,lD,lD2;
        lBondGraph->getStateMatrix(lA,lB,lB2);
        lBondGraph->getOutputMatrix(lC,lD,lD2);
        PACC::XML::Streamer lStream(cerr);
        lA.write(lStream);
        cerr << endl;
        lB.write(lStream);
        cerr << endl;
        lC.write(lStream);
        cerr << endl;
        lD.write(lStream);
        cerr << endl;

        //Save bond graph for debuging
        std::ostringstream lFilename;
        lFilename << "bug/bondgraph_bug_" << ioContext.getGeneration() << "_" << ioContext.getIndividualIndex();
#ifndef WITHOUT_GRAPHVIZ
        lBondGraph->plotGraph(lFilename.str()+std::string(".svg"));
#endif
        ofstream lFileStream((lFilename.str()+std::string(".xml")).c_str());
        PACC::XML::Streamer lStreamer(lFileStream);
        lBondGraph->write(lStreamer);

#ifdef STOP_ON_ERROR
        exit(EXIT_FAILURE);
#endif
    }
    catch(std::runtime_error inError) {
        std::cerr << "Error catched while evaluating the bond graph: " << inError.what() << std::endl;

        //Save bond graph for debuging
        std::ostringstream lFilename;
        lFilename << "bug/bondgraph_bug_" << ioContext.getGeneration() << "_" << ioContext.getIndividualIndex();
#ifndef WITHOUT_GRAPHVIZ
        lBondGraph->plotGraph(lFilename.str()+std::string(".svg"));
#endif
        ofstream lFileStream((lFilename.str()+std::string(".xml")).c_str());
        PACC::XML::Streamer lStreamer(lFileStream);
        lBondGraph->write(lStreamer);

        //Assign null fitness
        lFitness->setValue(0);

#ifdef XMLBEAGLE
        XMLStreamer lStreamer2(std::cout);
        inIndividual.write(lStreamer2);
#else
        inIndividual.write(lStreamer);
#endif

#ifdef STOP_ON_ERROR
        exit(EXIT_FAILURE);
#endif
    }

    //delete lBondGraph;
    return lFitness;
}
/*!
 *  \brief Swap mutate a constrained GP individual.
 *  \param ioIndividual GP individual to swap mutate.
 *  \param ioContext Context of the evolution.
 *  \return True if the individual is effectively mutated, false if not.
 */
bool GP::MutationSwapDepthSelectiveConstrainedOp::mutate(Beagle::Individual& ioIndividual, Beagle::Context& ioContext)
{
	Beagle_StackTraceBeginM();
	GP::Individual& lIndividual  = castObjectT<GP::Individual&>(ioIndividual);
	GP::Context& lContext        = castObjectT<GP::Context&>(ioContext);
	double lDistrProba           = mDistributionProba->getWrappedValue();
	unsigned int lNumberAttempts = mNumberAttempts->getWrappedValue();
	bool lMutationDone           = false;
	
	//Select node to mutate
	unsigned int lChoosenTree = 0;
	unsigned int lChoosenNode = 0;
	
	bool lDoParameterSearch = (lContext.getSystem().getRandomizer().rollUniform(0.0, 1.0) <= mMutParameterPb->getWrappedValue());
	
	RouletteT< std::pair<unsigned int,unsigned int> > lRoulette;
	//Select primitive based on type
	for(unsigned int lTry = 0; lTry < 2; ++lTry) { //Do only twice
		std::vector<const std::type_info*> lDesiredTypes(1, ArgEph);
		DepthDependentSelectionOp::buildRoulette(lRoulette, lDesiredTypes, lIndividual, lContext,!lDoParameterSearch,lDoParameterSearch);
		
		if(lRoulette.size() == 0) {
			if(lDoParameterSearch) {
				Beagle_LogVerboseM(
								   ioContext.getSystem().getLogger(),
								   "mutation", "Beagle::GP::MutationSwapDepthSelectiveConstrainedOp",
								   string("No EphemeralDouble node found.")
								   );
			}
			else {
				Beagle_LogVerboseM(
								   ioContext.getSystem().getLogger(),
								   "mutation", "Beagle::GP::MutationSwapDepthSelectiveConstrainedOp",
								   string("No non EphemeralDouble node found.")
								   );
			}
			lDoParameterSearch = !lDoParameterSearch;
			if(lTry >= 1) {
				Beagle_LogVerboseM(
								   ioContext.getSystem().getLogger(),
								   "mutation", "Beagle::GP::MutationSwapDepthSelectiveConstrainedOp",
								   "Unable to GP standard mutate the individual"
								   );
				return false;
			}
		}
		else { 
			std::pair<unsigned int,unsigned int> lSelectedNode = lRoulette.select(ioContext.getSystem().getRandomizer());
			lChoosenTree = lSelectedNode.first;
			lChoosenNode = lSelectedNode.second;
			break;
		}
	}
	
	if(lDoParameterSearch) {
		Beagle_LogVerboseM(
						   ioContext.getSystem().getLogger(),
						   "mutation", "Beagle::GP::MutationSwapDepthSelectiveConstrainedOp",
						   string("Mutation applied only on EphemeralDouble node.")
						   );
	}
	else {
		Beagle_LogVerboseM(
						   ioContext.getSystem().getLogger(),
						   "mutation", "Beagle::GP::MutationSwapDepthSelectiveConstrainedOp",
						   string("Mutation applied on node that are not EphemeralDouble.")
						   );
	}
	
	GP::Tree& lTree = *lIndividual[lChoosenTree];
	if(lTree.size() == 0) return false;
	
	GP::Tree::Handle lOldTreeHandle = lContext.getGenotypeHandle();
	unsigned int lOldTreeIndex = lContext.getGenotypeIndex();
	lContext.setGenotypeHandle(lIndividual[lChoosenTree]);
	lContext.setGenotypeIndex(lChoosenTree);
	
	Beagle_LogDebugM(
					 ioContext.getSystem().getLogger(),
					 "mutation", "Beagle::GP::MutationSwapDepthSelectiveConstrainedOp",
					 std::string("Individual before constrained GP tree swap mutation: ")+ioIndividual.serialize()
					 );
	
	if(lTree.size() > 1) {
		bool lTypeNode = (lContext.getSystem().getRandomizer().rollUniform(0., 1.) < lDistrProba);
		//Clean the roulette to include only the choosen tree
		for(std::vector< std::pair<double, std::pair<unsigned int,unsigned int> > >::iterator lRouletteIter = lRoulette.begin(); lRouletteIter!=lRoulette.end();){
			if(lRouletteIter->second.first != lChoosenTree || (lTree[lRouletteIter->second.second].mPrimitive->getNumberArguments() != 0) != lTypeNode ) {
				lRouletteIter = lRoulette.erase(lRouletteIter++);
			} else {
				++lRouletteIter;
			}
		}
		if(lRoulette.size() > 0) 
			lChoosenNode = lRoulette.select(ioContext.getSystem().getRandomizer()).second;
	}
	
	if( !lDoParameterSearch || lRoulette.size() > 0 ) {
	
		Primitive::Handle lOriginalPrimitive = lTree[lChoosenNode].mPrimitive;
		
		Beagle_LogVerboseM(
						   ioContext.getSystem().getLogger(),
						   "mutation", "Beagle::GP::MutationSwapDepthSelectiveConstrainedOp",
						   std::string("Trying to constrained GP tree swap mutate the ")+uint2ordinal(lChoosenNode+1)+
						   std::string(" node (primitive: \"")+lOriginalPrimitive->getName()+
						   std::string("\" nb args: ")+uint2str(lOriginalPrimitive->getNumberArguments())+
						   std::string(") of the ")+uint2ordinal(lChoosenTree+1)+std::string(" tree")
						   );
		
		GP::PrimitiveSet& lPrimitiveSet = lTree.getPrimitiveSet(lContext);
		unsigned int lNbArgsPrimit = lTree[lChoosenNode].mPrimitive->getNumberArguments();
		lTree.setContextToNode(lChoosenNode, lContext);
		for(unsigned int lAttempt=0; lAttempt < lNumberAttempts; ++lAttempt) {
			Primitive::Handle lChoosenPrimitive = lPrimitiveSet.select(lNbArgsPrimit, lContext);
			if(lChoosenPrimitive==NULL) break;
			
			lTree[lChoosenNode].mPrimitive = lChoosenPrimitive->giveReference(lNbArgsPrimit, lContext);
			
			Beagle_LogVerboseM(
							   ioContext.getSystem().getLogger(),
							   "mutation", "Beagle::GP::MutationSwapDepthSelectiveConstrainedOp",
							   std::string("Trying the primitive \"")+lChoosenPrimitive->getName()+
							   std::string("\"")
							   );
			
			if(lTree.validateSubTree(lChoosenNode, lContext)) {
				lMutationDone = true;
				Beagle_LogVerboseM(
								   ioContext.getSystem().getLogger(),
								   "mutation", "Beagle::GP::MutationSwapDepthSelectiveConstrainedOp",
								   "Constrained GP tree swap mutation valid"
								   );
				break;
			}
			else {
				lTree[lChoosenNode].mPrimitive = lOriginalPrimitive;
				Beagle_LogVerboseM(
								   ioContext.getSystem().getLogger(),
								   "mutation", "Beagle::GP::MutationSwapDepthSelectiveConstrainedOp",
								   "Constrained GP tree swap mutation invalid"
								   );
			}
		}
	}
	
	lContext.setGenotypeHandle(lOldTreeHandle);
	lContext.setGenotypeIndex(lOldTreeIndex);
	
	if(lMutationDone) {
		if( !lDoParameterSearch ) {
			//Set structure id invalid
			castHandleT<TreeSTag>((lIndividual)[0])->setStructureIDInvalid();
			Beagle_LogVerboseM(
							   ioContext.getSystem().getLogger(),
							   "mutation", "Beagle::GP::MutationSwapDepthSelectiveConstrainedOp",
							   std::string("Set structure id invalid") );
		}
		
		Beagle_LogDebugM(
						 ioContext.getSystem().getLogger(),
						 "mutation", "Beagle::GP::MutationSwapDepthSelectiveConstrainedOp",
						 std::string("Individual after constrained GP swap mutation: ")+
						 ioIndividual.serialize()
						 );
	}
	else {
		Beagle_LogVerboseM(
						   ioContext.getSystem().getLogger(),
						   "mutation", "Beagle::GP::MutationSwapDepthSelectiveConstrainedOp",
						   "Unable to swap mutate the constrained individual"
						   );
	}
	
	return lMutationDone;
	Beagle_StackTraceEndM("bool GP::MutationSwapDepthSelectiveConstrainedOp::mutate(Beagle::Individual& ioIndividual, Beagle::Context& ioContext)");
}
Exemplo n.º 15
0
/*!
 *  \brief Mate two GP individuals for a crossover.
 *  \param ioIndiv1   First individual to mate.
 *  \param ioContext1 Evolutionary context of the first individual.
 *  \param ioIndiv2   Second individual to mate.
 *  \param ioContext2 Evolutionary context of the second individual.
 *  \return True if the individuals are effectively mated, false if not.
 */
bool GP::CrossoverOp::mate(Beagle::Individual& ioIndiv1, Beagle::Context& ioContext1,
                           Beagle::Individual& ioIndiv2, Beagle::Context& ioContext2)
{
	Beagle_StackTraceBeginM();
	// Initial parameters checks
	Beagle_AssertM(&ioIndiv1 != &ioIndiv2);
	Beagle_AssertM(ioIndiv1.size() > 0);
	Beagle_AssertM(ioIndiv1.size() == ioIndiv2.size());
	Beagle_ValidateParameterM(mNumberAttempts->getWrappedValue()>0,"gp.try",">0");

	// Cast method arguments.
	GP::Individual& lIndiv1   = castObjectT<GP::Individual&>(ioIndiv1);
	GP::Individual& lIndiv2   = castObjectT<GP::Individual&>(ioIndiv2);
	GP::Context&    lContext1 = castObjectT<GP::Context&>(ioContext1);
	GP::Context&    lContext2 = castObjectT<GP::Context&>(ioContext2);

	// Get parameters in local values, with the total number of nodes of an individual.
	bool             lMatingDone     = false;
	float            lDistrProba     = mDistributionProba->getWrappedValue();
	unsigned int     lMaxTreeDepth   = mMaxTreeDepth->getWrappedValue();
	GP::Tree::Handle lOldTreeHandle1 = lContext1.getGenotypeHandle();
	unsigned int     lOldTreeIndex1  = lContext1.getGenotypeIndex();
	GP::Tree::Handle lOldTreeHandle2 = lContext2.getGenotypeHandle();
	unsigned int     lOldTreeIndex2  = lContext2.getGenotypeIndex();
	unsigned int     lSizeIndiv1     = 0;
	for(unsigned int i=0; i<lIndiv1.size(); i++) lSizeIndiv1 += lIndiv1[i]->size();

	Beagle_LogDebugM(
	    ioContext1.getSystem().getLogger(),
	    "crossover",
	    "Beagle::GP::CrossoverOp",
	    "Individuals to mate (before GP crossover)"
	);
	Beagle_LogObjectDebugM(
	    ioContext1.getSystem().getLogger(),
	    "crossover",
	    "Beagle::GP::CrossoverOp",
	    lIndiv1
	);
	Beagle_LogObjectDebugM(
	    ioContext1.getSystem().getLogger(),
	    "crossover",
	    "Beagle::GP::CrossoverOp",
	    lIndiv2
	);

	// Crossover loop. Try the given number of attempts to mate two individuals.
	for(unsigned int lAttempt=0; lAttempt<mNumberAttempts->getWrappedValue(); lAttempt++) {

		// Choose a node in all the individual node.
		unsigned int lChoosenNode1 =
		    lContext1.getSystem().getRandomizer().rollInteger(0, lSizeIndiv1-1);

		// Get the tree in which the choosen node is. Change the global
		// node index to the tree's index.
		unsigned int lChoosenTree1 = 0;
		for(; lChoosenTree1<lIndiv1.size(); lChoosenTree1++) {
			if(lChoosenNode1 < lIndiv1[lChoosenTree1]->size()) break;
			Beagle_AssertM(lChoosenNode1 >= lIndiv1[lChoosenTree1]->size());
			lChoosenNode1 -= lIndiv1[lChoosenTree1]->size();
		}
		Beagle_AssertM(lChoosenTree1 < lIndiv1.size());

		// Choose a type of node (branch or leaf) following the
		// distribution probability and change the node for another node
		// of the same tree if the types mismatch.
		GP::Tree& lTree1 = *lIndiv1[lChoosenTree1];
		const unsigned int lPrimitiveSetIndex1 = lTree1.getPrimitiveSetIndex();
		if(lTree1.size() > 1) {
			bool lTypeNode1 =
			    (lContext1.getSystem().getRandomizer().rollUniform(0.0, 1.0) < lDistrProba);
			while((lTree1[lChoosenNode1].mPrimitive->getNumberArguments() != 0) != lTypeNode1) {
				lChoosenNode1 = lContext1.getSystem().getRandomizer().rollInteger(0, lTree1.size()-1);
			}
		}

		// Choose a node in the second individual from a tree with the same primitive set index.
		unsigned int lSizeIndiv2 = 0;
		for(unsigned int i=0; i<lIndiv2.size(); i++) {
			if(lIndiv2[i]->getPrimitiveSetIndex() == lPrimitiveSetIndex1) {
				lSizeIndiv2 += lIndiv2[i]->size();
			}
		}

		// Check to see that there is at least one node that can be selected
		if(lSizeIndiv2==0) {
			Beagle_LogVerboseM(
			    ioContext1.getSystem().getLogger(),
			    "crossover", "Beagle::GP::CrossoverConstrainedOp",
			    std::string("Crossover attempt failed:  The tree chosen from the first individual has")+
			    " a primitive set index of "+uint2str(lPrimitiveSetIndex1)+
			    " and there are no trees in the second individual with that primitive set index"
			);
			continue;
		}

		// Choose a node in the second individual
		unsigned int lChoosenNode2 = lContext2.getSystem().getRandomizer().rollInteger(0, lSizeIndiv2-1);

		// Find which tree the choosen node is in.
		unsigned int lChoosenTree2 = 0;
		for(; lChoosenTree2<lIndiv2.size(); lChoosenTree2++) {
			if(lIndiv2[lChoosenTree2]->getPrimitiveSetIndex() == lPrimitiveSetIndex1) {
				if(lChoosenNode2 < lIndiv2[lChoosenTree2]->size()) break;
				Beagle_AssertM(lChoosenNode2 >= lIndiv2[lChoosenTree2]->size());
				lChoosenNode2 -= lIndiv2[lChoosenTree2]->size();
			}
		}
		Beagle_AssertM(lChoosenTree2 < lIndiv2.size());
		GP::Tree& lTree2 = *lIndiv2[lChoosenTree2];

		// Choose a type of node (branch or leaf) following the
		// distribution probability and change the node for another node
		// of the same tree if the types mismatch.
		if(lTree2.size() > 1) {
			bool lTypeNode2 =
			    (lContext2.getSystem().getRandomizer().rollUniform(0.0, 1.0) < lDistrProba);
			while((lTree2[lChoosenNode2].mPrimitive->getNumberArguments() != 0) != lTypeNode2) {
				lChoosenNode2 = lContext2.getSystem().getRandomizer().rollInteger(0, lTree2.size()-1);
			}
		}

		// Set the first context to the node of the first tree.
		// Check if depth is ok. Do a new crossover attempt if not.
		lTree1.setContextToNode(lChoosenNode1, lContext1);
		unsigned int lNewDepthTree1 =
		    lContext1.getCallStackSize() + lTree2.getTreeDepth(lChoosenNode2) - 1;
		if(lNewDepthTree1 > lMaxTreeDepth) {
			Beagle_LogVerboseM(
			    ioContext1.getSystem().getLogger(),
			    "crossover", "Beagle::GP::CrossoverConstrainedOp",
			    std::string("Crossover attempt failed because the depth of the resulting tree in the ")+
			    std::string("first individual would exceed the depth constraint")
			);
			continue;
		}

		// Set the first context to the node of the second tree.
		// Check if depth is ok. Do a new crossover attempt if not.
		lTree2.setContextToNode(lChoosenNode2, lContext2);
		unsigned int lNewDepthTree2 =
		    lContext2.getCallStackSize() + lTree1.getTreeDepth(lChoosenNode1) - 1;
		if(lNewDepthTree2 > lMaxTreeDepth) {
			Beagle_LogVerboseM(
			    ioContext1.getSystem().getLogger(),
			    "crossover", "Beagle::GP::CrossoverConstrainedOp",
			    std::string("Crossover attempt failed because the depth of the resulting tree in the ")+
			    std::string("second individual would exceed the depth constraint")
			);
			continue;
		}

		// Mate the trees.
		Beagle_LogVerboseM(
		    ioContext1.getSystem().getLogger(),
		    "crossover", "Beagle::GP::CrossoverOp",
		    std::string("Trying to mate the ")+uint2ordinal(lChoosenTree1+1)+
		    std::string(" tree of the first individual with the ")+uint2ordinal(lChoosenTree2+1)+
		    std::string(" tree of the second individual")
		);
		Beagle_LogVerboseM(
		    ioContext1.getSystem().getLogger(),
		    "crossover", "Beagle::GP::CrossoverOp",
		    std::string("Trying to exchange the ")+uint2ordinal(lChoosenNode1+1)+
		    std::string(" node of the first tree with the ")+uint2ordinal(lChoosenNode2+1)+
		    std::string(" node of the second tree")
		);

		mateTrees(lTree1, lChoosenNode1, lContext1, lTree2, lChoosenNode2, lContext2);

		lMatingDone = true;
		Beagle_LogVerboseM(
		    ioContext1.getSystem().getLogger(),
		    "crossover", "Beagle::GP::CrossoverOp",
		    "GP crossover valid"
		);
		break;   // The crossover is valid.
	}

	// Replace the contexts.
	lContext1.setGenotypeHandle(lOldTreeHandle1);
	lContext1.setGenotypeIndex(lOldTreeIndex1);
	lContext2.setGenotypeHandle(lOldTreeHandle2);
	lContext2.setGenotypeIndex(lOldTreeIndex2);

	if(lMatingDone) {
		Beagle_LogDebugM(
		    ioContext1.getSystem().getLogger(),
		    "crossover",
		    "Beagle::GP::CrossoverOp",
		    "Individuals mated (after GP crossover)"
		);
		Beagle_LogObjectDebugM(
		    ioContext1.getSystem().getLogger(),
		    "crossover",
		    "Beagle::GP::CrossoverOp",
		    lIndiv1
		);
		Beagle_LogObjectDebugM(
		    ioContext1.getSystem().getLogger(),
		    "crossover",
		    "Beagle::GP::CrossoverOp",
		    lIndiv2
		);
	} else {
		Beagle_LogVerboseM(
		    ioContext1.getSystem().getLogger(),
		    "crossover", "Beagle::GP::CrossoverOp",
		    "No GP crossover done"
		);
	}

	return lMatingDone;
	Beagle_StackTraceEndM("bool GP::CrossoverOp::mate(Beagle::Individual& ioIndiv1, Beagle::Context& ioContext1, Beagle::Individual& ioIndiv2, Beagle::Context& ioContext2)");
}
/*!
 *  \brief Standard mutate a constrained GP individual.
 *  \param ioIndividual GP individual to standard mutate.
 *  \param ioContext Context of the evolution.
 *  \return True if the individual is effectively mutated, false if not.
 */
bool GP::MutationStandardSelectiveConstrainedOp::mutate(Beagle::Individual& ioIndividual, Beagle::Context& ioContext)
{
	Beagle_StackTraceBeginM();
	GP::Individual& lIndividual        = castObjectT<GP::Individual&>(ioIndividual);
	GP::Context& lContext              = castObjectT<GP::Context&>(ioContext);
	unsigned int lMaxTreeDepth         = mMaxTreeDepth->getWrappedValue();
	unsigned int lMaxRegenerationDepth = mMaxRegenerationDepth->getWrappedValue();
	
	//Select node to mutate
	unsigned int lChoosenTree = 0;
	unsigned int lChoosenNode = 0;
	
	bool lDoParameterSearch = (lContext.getSystem().getRandomizer().rollUniform(0.0, 1.0) <= mMutParameterPb->getWrappedValue());
	
	//Select primitive based on type
	for(unsigned int lTry = 0; lTry < 2; ++lTry) { //Do only twice
		std::vector<const std::type_info*> lDesiredTypes(1, ArgEph);
		RouletteT< std::pair<unsigned int,unsigned int> > lRoulette;
		SelectiveConstrainedSelectionOp::buildRoulette(lRoulette, lDesiredTypes, lIndividual, lContext,!lDoParameterSearch,lDoParameterSearch);
		
		if(lRoulette.size() == 0) {
			if(lDoParameterSearch) {
				Beagle_LogVerboseM(
								   ioContext.getSystem().getLogger(),
								   "mutation", "Beagle::GP::MutationStandardSelectiveConstrainedOp",
								   string("No EphemeralDouble node found.")
								   );
			}
			else {
				Beagle_LogVerboseM(
								   ioContext.getSystem().getLogger(),
								   "mutation", "Beagle::GP::MutationStandardSelectiveConstrainedOp",
								   string("No non EphemeralDouble node found.")
								   );
			}
			lDoParameterSearch = !lDoParameterSearch;
			if(lTry >= 1) {
				Beagle_LogVerboseM(
								   ioContext.getSystem().getLogger(),
								   "mutation", "Beagle::GP::MutationStandardSelectiveConstrainedOp",
								   "Unable to GP standard mutate the individual"
								   );
				return false;
			}
		}
		else { 
			std::pair<unsigned int,unsigned int> lSelectedNode = lRoulette.select(ioContext.getSystem().getRandomizer());
			lChoosenTree = lSelectedNode.first;
			lChoosenNode = lSelectedNode.second;
			break;
		}
	}
	
	if(lDoParameterSearch) {
		Beagle_LogVerboseM(
						   ioContext.getSystem().getLogger(),
						   "mutation", "Beagle::GP::MutationStandardSelectiveConstrainedOp",
						   string("Mutation applied only on EphemeralDouble node.")
						   );
	}
	else {
		Beagle_LogVerboseM(
						   ioContext.getSystem().getLogger(),
						   "mutation", "Beagle::GP::MutationStandardSelectiveConstrainedOp",
						   string("Mutation applied on node that are not EphemeralDouble.")
						   );
	}
	
	
	unsigned int lOldGenotypeIndex = lContext.getGenotypeIndex();
	GP::Tree::Handle lOldGenotypeHandle = lContext.getGenotypeHandle();
	
	Beagle_LogDebugM(
					 ioContext.getSystem().getLogger(),
					 "mutation", "Beagle::GP::MutationStandardSelectiveConstrainedOp",
					 std::string("Individual before GP standard mutation: ")+
					 ioIndividual.serialize()
					 );
	
	GP::Tree::Handle lActualTree = lIndividual[lChoosenTree];
	GP::Tree::Handle lNewTree    = castHandleT<GP::Tree>(lIndividual.getTypeAlloc()->allocate());
	lNewTree->setPrimitiveSetIndex(lActualTree->getPrimitiveSetIndex());
	lNewTree->setNumberArguments(lActualTree->getNumberArguments());
	unsigned int lChoosenNodeSubTreeSize = (*lActualTree)[lChoosenNode].mSubTreeSize;
	lNewTree->insert(lNewTree->end(), lActualTree->begin(), lActualTree->begin()+lChoosenNode);
	lContext.setGenotypeIndex(lChoosenTree);
	lContext.setGenotypeHandle(lActualTree);
	lContext.emptyCallStack();
	lActualTree->setContextToNode(lChoosenNode, lContext);
	lContext.popCallStack();
	const unsigned int lMaxSubTreeDepth =
    minOf<unsigned int>(lMaxTreeDepth - lContext.getCallStackSize(), lMaxRegenerationDepth);
	lIndividual[lChoosenTree] = lNewTree;
	lContext.setGenotypeHandle(lNewTree);
	
	unsigned int lAttempt=0;
	if(lMaxSubTreeDepth >= 1) {
		for(; lAttempt < mNumberAttempts->getWrappedValue(); lAttempt++) {
			if(mInitOp->initTree(*lNewTree, 1, lMaxSubTreeDepth, lContext) != 0) break;
		}
	} else {
		lAttempt = mNumberAttempts->getWrappedValue();
	}
	
	if(lAttempt == mNumberAttempts->getWrappedValue()) {
		lIndividual[lChoosenTree] = lActualTree;
		lContext.setGenotypeIndex(lOldGenotypeIndex);
		lContext.setGenotypeHandle(lOldGenotypeHandle);
		Beagle_LogVerboseM(
						   ioContext.getSystem().getLogger(),
						   "mutation", "Beagle::GP::MutationStandardSelectiveConstrainedOp",
						   "Unable to GP standard mutate the individual"
						   );
		return false;
	}
	
	if( !lDoParameterSearch ) {
		//Set structure id invalid
		castHandleT<TreeSTag>((lIndividual)[0])->setStructureIDInvalid();
		Beagle_LogVerboseM(
						   ioContext.getSystem().getLogger(),
						   "mutation", "Beagle::GP::MutationStandardSelectiveConstrainedOp",
						   std::string("Set structure id invalid") );
	}
	
	Beagle_LogVerboseM(
					   ioContext.getSystem().getLogger(),
					   "mutation", "Beagle::GP::MutationStandardSelectiveConstrainedOp",
					   std::string("GP standard mutate the ")+uint2ordinal(lChoosenNode+1)+
					   std::string(" node, ")+ (*lActualTree)[lChoosenNode].mPrimitive->getName()
					   +std::string(", of the ")+uint2ordinal(lChoosenTree+1)+
					   std::string(" tree with max depth ")+uint2str(lMaxSubTreeDepth)
					   );
	
	lNewTree->insert(lNewTree->end(),
					 lActualTree->begin()+lChoosenNode+lChoosenNodeSubTreeSize,
					 lActualTree->end());
	unsigned int lDiffSize =
    (*lActualTree)[lChoosenNode].mSubTreeSize - (*lNewTree)[lChoosenNode].mSubTreeSize;
	for(unsigned int l=0; l<lContext.getCallStackSize(); l++) {
		(*lNewTree)[lContext.getCallStackElement(l)].mSubTreeSize -= lDiffSize;
	}
	
	lContext.setGenotypeIndex(lOldGenotypeIndex);
	lContext.setGenotypeHandle(lOldGenotypeHandle);
	
	Beagle_LogDebugM(
					 ioContext.getSystem().getLogger(),
					 "mutation", "Beagle::GP::MutationStandardSelectiveConstrainedOp",
					 std::string("Individual after GP standard mutation: ")+
					 ioIndividual.serialize()
					 );
	
	return true;
	Beagle_StackTraceEndM("bool GP::MutationStandardSelectiveConstrainedOp::mutate(Beagle::Individual& ioIndividual, Beagle::Context& ioContext)");
}
/*!
 *  \brief Mate two indice integer vector GA individuals for non-wrapping ordered crossover.
 *  \param ioIndiv1   First individual to mate.
 *  \param ioContext1 Evolutionary context of the first individual.
 *  \param ioIndiv2   Second individual to mate.
 *  \param ioContext2 Evolutionary context of the second individual.
 *  \return True if the individuals are effectively mated, false if not.
 */
bool Beagle::GA::CrossoverNWOXOp::mate(Beagle::Individual& ioIndiv1,
									   Beagle::Context&    ioContext1,
									   Beagle::Individual& ioIndiv2,
									   Beagle::Context&    ioContext2)
{
	Beagle_StackTraceBeginM();
	unsigned int lNbGenotypes = minOf<unsigned int>(ioIndiv1.size(), ioIndiv2.size());
	if(lNbGenotypes == 0) return false;
	
	Beagle_LogDebugM(
					 ioContext1.getSystem().getLogger(),
					 "crossover", "Beagle::GA::CrossoverNWOXOp",
					 "Individuals mated (before GA non-wrapping ordered crossover)"
					 );
	Beagle_LogObjectDebugM(
						   ioContext1.getSystem().getLogger(),
						   "crossover", "Beagle::GA::CrossoverNWOXOp",
						   ioIndiv1
						   );
	Beagle_LogObjectDebugM(
						   ioContext1.getSystem().getLogger(),
						   "crossover", "Beagle::GA::CrossoverNWOXOp",
						   ioIndiv2
						   );
	
	for(unsigned int i=0; i<lNbGenotypes; ++i) {
		GA::IntegerVector::Handle lIndividual1 = castHandleT<IntegerVector>(ioIndiv1[i]);
		GA::IntegerVector::Handle lIndividual2 = castHandleT<IntegerVector>(ioIndiv2[i]);
		
		unsigned int lSize = minOf<unsigned int>(lIndividual1->size(), lIndividual2->size());
		unsigned int a = ioContext1.getSystem().getRandomizer().rollInteger(0, lSize-1);
		unsigned int b = ioContext1.getSystem().getRandomizer().rollInteger(0, lSize-1);
		
		if(a > b){std::swap(a, b);}
		bool* lHoleSet1 = new bool[lSize];
		bool* lHoleSet2 = new bool[lSize];
		for(unsigned int j = 0; j < lSize; ++j){
			if(j < a || j > b){
				lHoleSet1[(*lIndividual2)[j]] = false;
				lHoleSet2[(*lIndividual1)[j]] = false;
			}else{
				lHoleSet1[(*lIndividual2)[j]] = true;
				lHoleSet2[(*lIndividual1)[j]] = true;
			}
		}
		std::vector<unsigned int> lChild1;
		std::vector<unsigned int> lChild2;
		for(unsigned int j = 0; j < lSize; ++j){
			if(!lHoleSet1[(*lIndividual1)[j]])
				lChild1.push_back((*lIndividual1)[j]);
			
			if(!lHoleSet2[(*lIndividual2)[j]])
				lChild2.push_back((*lIndividual2)[j]);
		}
		lChild1.insert(lChild1.begin() + a, lIndividual2->begin() + a, lIndividual2->begin() + (b + 1));
		lChild2.insert(lChild2.begin() + a, lIndividual1->begin() + a, lIndividual1->begin() + (b + 1));
		// Transfer the child in the ouput individuals
		for(unsigned int j = 0; j < lSize; ++j){
			(*lIndividual1)[j] = lChild1[j];
			(*lIndividual2)[j] = lChild2[j];
		}
		
		delete[] lHoleSet1;
		delete[] lHoleSet2;
	}
	
	Beagle_LogDebugM(
					 ioContext1.getSystem().getLogger(),
					 "crossover", "Beagle::GA::CrossoverNWOXOp",
					 "Individuals mated (after GA non-wrapping ordered crossover)"
					 );
	Beagle_LogObjectDebugM(
						   ioContext1.getSystem().getLogger(),
						   "crossover",
						   "Beagle::GA::CrossoverNWOXOp",
						   ioIndiv1
						   );
	Beagle_LogObjectDebugM(
						   ioContext1.getSystem().getLogger(),
						   "crossover",
						   "Beagle::GA::CrossoverNWOXOp",
						   ioIndiv2
						   );
	
	return true;
	Beagle_StackTraceEndM("bool GA::CrossoverNWOXOp::mate(Individual& ioIndiv1, Context& ioContext1, Individual& ioIndiv2, Context& ioContext2)");
}
/*!
 *  \brief Mate two indice integer vector GA individuals for partialy matched crossover.
 *  \param ioIndiv1   First individual to mate.
 *  \param ioContext1 Evolutionary context of the first individual.
 *  \param ioIndiv2   Second individual to mate.
 *  \param ioContext2 Evolutionary context of the second individual.
 *  \return True if the individuals are effectively mated, false if not.
 */
bool Beagle::GA::CrossoverPMXOp::mate(Beagle::Individual& ioIndiv1,
									  Beagle::Context&    ioContext1,
									  Beagle::Individual& ioIndiv2,
									  Beagle::Context&    ioContext2)
{
	Beagle_StackTraceBeginM();
	unsigned int lNbGenotypes = minOf<unsigned int>(ioIndiv1.size(), ioIndiv2.size());
	if(lNbGenotypes == 0) return false;
	
	Beagle_LogDebugM(
					 ioContext1.getSystem().getLogger(),
					 "crossover", "Beagle::GA::CrossoverPMXOp",
					 "Individuals mated (before GA partily matched crossover)"
					 );
	Beagle_LogObjectDebugM(
						   ioContext1.getSystem().getLogger(),
						   "crossover", "Beagle::GA::CrossoverPMXOp",
						   ioIndiv1
						   );
	Beagle_LogObjectDebugM(
						   ioContext1.getSystem().getLogger(),
						   "crossover", "Beagle::GA::CrossoverPMXOp",
						   ioIndiv2
						   );
	
	for(unsigned int i=0; i<lNbGenotypes; ++i) {
		GA::IntegerVector::Handle lIndividual1 = castHandleT<IntegerVector>(ioIndiv1[i]);
		GA::IntegerVector::Handle lIndividual2 = castHandleT<IntegerVector>(ioIndiv2[i]);
		
		std::deque<int> lIndividual1Copy(lIndividual1->begin(), lIndividual1->end());
		std::deque<int> lIndividual2Copy(lIndividual2->begin(), lIndividual2->end());
		
		unsigned int lSize = minOf<unsigned int>(lIndividual1->size(), lIndividual2->size());
		unsigned int a = ioContext1.getSystem().getRandomizer().rollInteger(0, lSize-1);
		unsigned int b = ioContext1.getSystem().getRandomizer().rollInteger(0, lSize-1);
		
		if(a > b){std::swap(a, b);}
		for(unsigned int j = a; j <= b; ++j){
			for(unsigned int k = 0; k < lSize; ++k){
				if((*lIndividual1)[k] == lIndividual1Copy[j])
					(*lIndividual1)[k] = lIndividual2Copy[j];
				else if((*lIndividual1)[k] == lIndividual2Copy[j])
					(*lIndividual1)[k] = lIndividual1Copy[j];
				
				if((*lIndividual2)[k] == lIndividual1Copy[j])
					(*lIndividual2)[k] = lIndividual2Copy[j];
				else if((*lIndividual2)[k] == lIndividual2Copy[j])
					(*lIndividual2)[k] = lIndividual1Copy[j];
			}
		}
	}
	
	Beagle_LogDebugM(
					 ioContext1.getSystem().getLogger(),
					 "crossover", "Beagle::GA::CrossoverPMXOp",
					 "Individuals mated (after GA partialy matched crossover)"
					 );
	Beagle_LogObjectDebugM(
						   ioContext1.getSystem().getLogger(),
						   "crossover",
						   "Beagle::GA::CrossoverPMXOp",
						   ioIndiv1
						   );
	Beagle_LogObjectDebugM(
						   ioContext1.getSystem().getLogger(),
						   "crossover",
						   "Beagle::GA::CrossoverPMXOp",
						   ioIndiv2
						   );
	
	return true;
	Beagle_StackTraceEndM("bool GA::CrossoverPMXOp::mate(Individual& ioIndiv1, Context& ioContext1, Individual& ioIndiv2, Context& ioContext2)");
}
Exemplo n.º 19
0
/*!
 *  \brief Gaussian mutate a real-valued GA individual.
 *  \param ioIndividual Real-valued GA individual to mutate.
 *  \param ioContext Context of the evolution.
 *  \return True if the individual is effectively mutated, false if not.
 */
bool FltVec::MutationGaussianOp::mutate(Beagle::Individual& ioIndividual, Context& ioContext)
{
	Beagle_StackTraceBeginM();
	bool lMutated = false;
	Beagle_LogVerboseM(
	    ioContext.getSystem().getLogger(),
	    string("Gaussian mutations with mean of ")+
	    mMutateGaussMu->serialize()+
	    string(", and standard deviation of ")+
	    mMutateGaussSigma->serialize()
	);

	for(unsigned int i=0; i<ioIndividual.size(); i++) {
		FltVec::FloatVector::Handle lVector = castHandleT<FltVec::FloatVector>(ioIndividual[i]);
		Beagle_LogVerboseM(
		    ioContext.getSystem().getLogger(),
		    string("Gaussian mutation the ")+uint2ordinal(i+1)+" float vector"
		);
		Beagle_LogDebugM(ioContext.getSystem().getLogger(), *lVector);
		for(unsigned int j=0; j<lVector->size(); j++) {
			const float lRolledPb = ioContext.getSystem().getRandomizer().rollUniform();
			if(lRolledPb <= mMutateFloatPb->getWrappedValue()) {
				const double lMaxVal = j<mMaxValue->size() ? (*mMaxValue)[j] : mMaxValue->back();
				const double lMinVal = j<mMinValue->size() ? (*mMinValue)[j] : mMinValue->back();
				const double lIncVal = j<mIncValue->size() ? (*mIncValue)[j] : mIncValue->back();
				const double lMu =
				    j<mMutateGaussMu->size() ? (*mMutateGaussMu)[j] : mMutateGaussMu->back();
				const double lSigma =
				    j<mMutateGaussSigma->size() ? (*mMutateGaussSigma)[j] : mMutateGaussSigma->back();
				Beagle_AssertM(lSigma>=0.0);
				const double lMValue = ioContext.getSystem().getRandomizer().rollGaussian(lMu,lSigma);
				(*lVector)[j] += lMValue;
				if((*lVector)[j] > lMaxVal) (*lVector)[j] = lMaxVal;
				if((*lVector)[j] < lMinVal) (*lVector)[j] = lMinVal;
				if(std::fabs(lIncVal)>1e-12) {
					(*lVector)[j] = lIncVal * round((*lVector)[j] / lIncVal);
					if((*lVector)[j] > lMaxVal) (*lVector)[j] -= lIncVal;
					if((*lVector)[j] < lMinVal) (*lVector)[j] += lIncVal;
				}
				lMutated = true;
				Beagle_LogDebugM(
				    ioContext.getSystem().getLogger(),
				    string("Gaussian mutating by adding ")+dbl2str(lMValue)+
				    string(" to the value at the index ")+uint2str(j)+
				    string(" of the float vector")
				);
			}
		}
		if(lMutated) {
			Beagle_LogVerboseM(
			    ioContext.getSystem().getLogger(),
			    "The float vector has been mutated"
			);
			Beagle_LogDebugM(ioContext.getSystem().getLogger(), *lVector);
		} else {
			Beagle_LogVerboseM(ioContext.getSystem().getLogger(), "The float vector has not been mutated");
		}
	}
	return lMutated;
	Beagle_StackTraceEndM();
}
Exemplo n.º 20
0
/*!
 *  \brief Swap subtree mutate a GP individual.
 *  \param ioIndividual GP individual to swap subtree mutate.
 *  \param ioContext Context of the evolution.
 */
bool GP::MutationSwapSubtreeOp::mutate(Beagle::Individual& ioIndividual, Beagle::Context& ioContext)
{
	Beagle_StackTraceBeginM();
	// Initial parameters checks.
	Beagle_AssertM(ioIndividual.size() > 0);
	Beagle_ValidateParameterM(mNumberAttempts->getWrappedValue()>0, "gp.try", ">0");

	// Cast method arguments.
	GP::Individual&     lGPIndiv      = castObjectT<GP::Individual&>(ioIndividual);
	GP::Context&        lContext1     = castObjectT<GP::Context&>(ioContext);
	Context::Alloc::Handle lContextAlloc =
	    castHandleT<Context::Alloc>(ioContext.getSystem().getFactory().getConceptAllocator("Context"));
	GP::Context::Handle lContextHdl2  = castHandleT<GP::Context>(lContextAlloc->clone(lContext1));

	const Factory& lFactory = ioContext.getSystem().getFactory();
	GP::Tree::Alloc::Handle lTreeAlloc =
		castHandleT<GP::Tree::Alloc>(lFactory.getConceptAllocator("Genotype"));

	// Get parameters in local values, with the total number of nodes of the mutated individual.
	bool             lMatingDone     = false;
	float            lDistrProba     = mDistributionProba->getWrappedValue();
	unsigned int     lMaxTreeDepth   = mMaxTreeDepth->getWrappedValue();
	GP::Tree::Handle lOldTreeHandle1 = lContext1.getGenotypeHandle();
	unsigned int     lOldTreeIndex1  = lContext1.getGenotypeIndex();
	unsigned int     lSizeIndiv      = 0;
	for(unsigned int i=0; i<lGPIndiv.size(); ++i) lSizeIndiv += lGPIndiv[i]->size();

	// Some outputs.
	Beagle_LogDebugM(
	    lContext1.getSystem().getLogger(),
	    "mutation",
	    "Beagle::GP::MutationSwapSubtreeOp",
	    "Individual tried for swap subtree mutation (before)"
	);
	Beagle_LogObjectDebugM(
	    lContext1.getSystem().getLogger(),
	    "mutation",
	    "Beagle::GP::MutationSwapSubtreeOp",
	    lGPIndiv
	);

	// Mutation loop. Try the given number of attempts to mutation the individual.
	for(unsigned int lAttempt=0; lAttempt < mNumberAttempts->getWrappedValue(); lAttempt++) {

		// Calculate the number of nodes in the individual
		unsigned int lNbNodes = 0;
		for(unsigned int i=0; i<lGPIndiv.size(); i++) lNbNodes += lGPIndiv[i]->size();
		if(lNbNodes == 0) return false;

		// Choose a node of the individual to mutate.
		unsigned int lNode1 = lContext1.getSystem().getRandomizer().rollInteger(0, lNbNodes-1);

		// Get the tree in which the choosen node is. Change the global node index to the tree's index.
		unsigned int lChoosenTree = 0;
		for(; lChoosenTree<lGPIndiv.size(); ++lChoosenTree) {
			if(lNode1 < lGPIndiv[lChoosenTree]->size()) break;
			Beagle_AssertM(lNode1 >= lGPIndiv[lChoosenTree]->size());
			lNode1 -= lGPIndiv[lChoosenTree]->size();
		}
		Beagle_AssertM(lChoosenTree < lGPIndiv.size());

		// Cannot do anything with an tree of size <= 1.
		if(lGPIndiv[lChoosenTree]->size() <= 1) continue;

		// Some outputs.
		Beagle_LogVerboseM(
		    lContext1.getSystem().getLogger(),
		    "mutation", "Beagle::GP::MutationSwapSubtreeOp",
		    std::string("Trying a swap subtree mutation of the ")+uint2ordinal(lChoosenTree+1)+
		    std::string(" tree")
		);

		// Make two clones of the choosen tree.
		GP::Tree::Handle lTreeClone1 = castHandleT<GP::Tree>(lTreeAlloc->clone(*lGPIndiv[lChoosenTree]));
		GP::Tree::Handle lTreeClone2 = castHandleT<GP::Tree>(lTreeAlloc->clone(*lGPIndiv[lChoosenTree]));

		// Now we decide whether the swap subtree mutation is internal or external.
		bool lMutationType = lContext1.getSystem().getRandomizer().rollUniform(0.0, 1.0) < lDistrProba;

		// Cannot do an internal mutation when there is only one branch in the tree.
		if(lTreeClone1->size() == (*lTreeClone1)[0].mPrimitive->getNumberArguments()+1)
			lMutationType = false;

		// This is special case, a linear tree. Cannot do an external mutation.
		if(lTreeClone1->size() == (*lTreeClone1)[1].mSubTreeSize+1) {
			if(lTreeClone1->size()==2) continue;   // Cannot do anything here with the tree.
			lMutationType = true;
		}

		// lMutationType is true -> internal mutation
		if(lMutationType)  {

			// If the selected node is a terminal, or a branch with a subtree made only of terminals,
			// choose another node in the same tree.
			while((*lTreeClone1)[lNode1].mSubTreeSize ==
			        ((*lTreeClone1)[lNode1].mPrimitive->getNumberArguments()+1)) {
				lNode1 = lContext1.getSystem().getRandomizer().rollInteger(0, lTreeClone1->size()-1);
			}

			// Choosing the second node, a branch in lNode1's subtree.
			unsigned int lSubTreeSizeN1 = (*lTreeClone1)[lNode1].mSubTreeSize;
			unsigned int lN2OffN1 =
			    lContext1.getSystem().getRandomizer().rollInteger(1, lSubTreeSizeN1-1);
			unsigned int lNode2 = lNode1 + lN2OffN1;
			while((*lTreeClone1)[lNode2].mPrimitive->getNumberArguments() == 0) {
				lN2OffN1 = lContext1.getSystem().getRandomizer().rollInteger(1, lSubTreeSizeN1-1);
				lNode2 = lNode1 + lN2OffN1;
			}

			// Choosing the third node, any node in lNode2's subtree.
			unsigned int lSubTreeSizeN2 = (*lTreeClone1)[lNode2].mSubTreeSize;
			unsigned int lN3OffN2 =
			    lContext1.getSystem().getRandomizer().rollInteger(1, lSubTreeSizeN2-1);

			// Ok, now we can exchange the subtrees.

			// New value of lNode1 and lNode2 for the second exchange.
			unsigned int lNode3Exch2 = lNode1 + lN3OffN2;
			unsigned int lNode1Exch2 = lNode2;

			// New value of lNode1 and lNode2 for the third exchange.
			unsigned int lNode2Exch3 = lNode1 + lN3OffN2 + lN2OffN1;
			unsigned int lNode3Exch3 = lNode2;

			// First exchange.
			lTreeClone1->setContextToNode(lNode1, lContext1);
			lTreeClone2->setContextToNode(lNode2, *lContextHdl2);
			exchangeSubTrees(*lTreeClone1, lNode1, lContext1,
			                 *lTreeClone2, lNode2, *lContextHdl2);

			// Second exchange.
			lTreeClone1->setContextToNode(lNode3Exch2, lContext1);
			lTreeClone2->setContextToNode(lNode1Exch2, *lContextHdl2);
			exchangeSubTrees(*lTreeClone1, lNode3Exch2, lContext1,
			                 *lTreeClone2, lNode1Exch2, *lContextHdl2);

			// Third exchange.
			lTreeClone1->setContextToNode(lNode2Exch3, lContext1);
			lTreeClone2->setContextToNode(lNode3Exch3, *lContextHdl2);
			exchangeSubTrees(*lTreeClone1, lNode2Exch3, lContext1,
			                 *lTreeClone2, lNode3Exch3, *lContextHdl2);

			// Checking if the tree depth is respected. If not, start again.
			if(lTreeClone1->getTreeDepth() > lMaxTreeDepth) {
				Beagle_LogVerboseM(
				    lContext1.getSystem().getLogger(),
				    "mutation", "Beagle::GP::MutationSwapSubtreeOp",
				    "Tree maximum depth exceeded. GP swap subtree mutation invalid."
				);
				continue;
			}

			lGPIndiv[lChoosenTree] = lTreeClone1;
			Beagle_LogVerboseM(
			    lContext1.getSystem().getLogger(),
			    "mutation", "Beagle::GP::MutationSwapSubtreeOp",
			    "GP swap subtree mutation valid"
			);
			lMatingDone = true;
			break;   // The swap subtree mutation is valid.
		}

		// lMutationType is false -> external mutation
		else {

			// Deterniming the minimal node index to use.
			unsigned int lMinNodeIndex = 0;
			for(; lTreeClone1->size() == ((*lTreeClone1)[lMinNodeIndex].mSubTreeSize+lMinNodeIndex);
			        ++lMinNodeIndex) {
				if(lMinNodeIndex == (lTreeClone1->size()-1)) continue; // Can't do anything with linear tree.
			}

			// Change lNode1 if less than minimum node index.
			if(lNode1 < lMinNodeIndex)
				lNode1 = lContext1.getSystem().getRandomizer().rollInteger(lMinNodeIndex,
				         lTreeClone1->size()-1);

			// Choosing second swap subtree mutation point.
			std::vector<unsigned int> lValidN2;
			for(unsigned int i=lMinNodeIndex; i<lTreeClone1->size(); ++i) {
				if((i>=lNode1) && (i<lNode1+(*lTreeClone1)[lNode1].mSubTreeSize)) continue;
				else if((lNode1>=i) && (lNode1<(i+(*lTreeClone1)[i].mSubTreeSize))) continue;
				else lValidN2.push_back(i);
			}
			unsigned int lNode2 =
			    lValidN2[lContext1.getSystem().getRandomizer().rollInteger(0, lValidN2.size()-1)];

			Beagle_LogVerboseM(
			    lContext1.getSystem().getLogger(),
			    "mutation", "Beagle::GP::MutationSwapSubtreeOp",
			    std::string("Trying an external swap subtree mutation of the ")+uint2ordinal(lNode1+1)+
			    std::string(" node with the subtree to the ")+uint2ordinal(lNode2+1)+
			    std::string(" node")
			);

			// Ok, now we can exchange the subtrees.

			// New value of lNode1 and lNode2 for the second exchange.
			unsigned int lNode1Exch2 = lNode1;
			unsigned int lNode2Exch2 = lNode2;
			if(lNode1 < lNode2) {
				lNode2Exch2 += (*lTreeClone1)[lNode2].mSubTreeSize;
				lNode2Exch2 -= (*lTreeClone1)[lNode1].mSubTreeSize;
			} else {
				lNode1Exch2 += (*lTreeClone1)[lNode1].mSubTreeSize;
				lNode1Exch2 -= (*lTreeClone1)[lNode2].mSubTreeSize;
			}

			// First exchange.
			lTreeClone1->setContextToNode(lNode1, lContext1);
			lTreeClone2->setContextToNode(lNode2, *lContextHdl2);
			exchangeSubTrees(*lTreeClone1, lNode1, lContext1,
			                 *lTreeClone2, lNode2, *lContextHdl2);

			// Second exchange.
			lTreeClone1->setContextToNode(lNode2Exch2, lContext1);
			lTreeClone2->setContextToNode(lNode1Exch2, *lContextHdl2);
			exchangeSubTrees(*lTreeClone1, lNode2Exch2, lContext1,
			                 *lTreeClone2, lNode1Exch2, *lContextHdl2);

			// Checking if the tree depth is respected. If not, start again.
			if(lTreeClone1->getTreeDepth() > lMaxTreeDepth) {
				Beagle_LogVerboseM(
				    lContext1.getSystem().getLogger(),
				    "mutation", "Beagle::GP::MutationSwapSubtreeOp",
				    "Tree maximum depth exceeded. GP swap subtree mutation invalid."
				);
				continue;
			}

			lGPIndiv[lChoosenTree] = lTreeClone1;
			Beagle_LogVerboseM(
			    lContext1.getSystem().getLogger(),
			    "mutation", "Beagle::GP::MutationSwapSubtreeOp",
			    "GP swap subtree mutation valid"
			);
			lMatingDone = true;
			break;   // The swap subtree mutation is valid.
		}
	}

	// Replace the contexts.
	lContext1.setGenotypeHandle(lOldTreeHandle1);
	lContext1.setGenotypeIndex(lOldTreeIndex1);

	if(lMatingDone) {
		Beagle_LogDebugM(
		    lContext1.getSystem().getLogger(),
		    "mutation",
		    "Beagle::GP::MutationSwapSubtreeOp",
		    "Individual after swap subtree mutation"
		);
		Beagle_LogObjectDebugM(
		    lContext1.getSystem().getLogger(),
		    "mutation",
		    "Beagle::GP::MutationSwapSubtreeOp",
		    lGPIndiv
		);
	} else {
		Beagle_LogVerboseM(
		    lContext1.getSystem().getLogger(),
		    "mutation", "Beagle::GP::MutationSwapSubtreeOp",
		    "No GP swap subtree mutation done"
		);
	}

	return lMatingDone;
	Beagle_StackTraceEndM();
}