/*!
 *  \brief Compile a shared library for evaluating the fitness of each individual in deme specified.
 *  \param ioDeme Reference to the deme for which to compile a shared library.
 *  \param ioContext Evolutionary context of the operation.
 *
 */
void SharedLibCompileOp::operate(Beagle::Deme& ioDeme, Beagle::Context& ioContext)
{  
    Beagle_StackTraceBeginM();

	std::string lPathLib;

    /* The abstract class Operator is defined in the namespace Beagle.
    * Thus, the Context passed in is from Beagle as well.
    * However, Beagle::GP::Individual::deparse requires a Beagle::GP::Context.
    * Cast the Beagle::Context passed in to a Beagle::GP::Context.
    */
    Beagle::GP::Context lContext= Beagle::castObjectT<Beagle::GP::Context&>(ioContext);

	// Create a SharedLibCompiler.
    int lNrColumns= castHandleT<Int>(ioContext.getSystem().getRegister()["icu.dataset.columns"])->getWrappedValue();
    std::string lTmpDirectory= castHandleT<String>(ioContext.getSystem().getRegister()["icu.compiler.tmp-directory"])->getWrappedValue();
    SharedLibCompiler lSharedLibCompiler(lNrColumns, lTmpDirectory);
    
    // Add individuals, compile.
    for(Beagle::Deme::const_iterator lIndividual=ioDeme.begin(); lIndividual!=ioDeme.end(); ++lIndividual)
    {
        Beagle::GP::Individual::Handle lGPIndividual= castHandleT<Beagle::GP::Individual>(*lIndividual);
		lSharedLibCompiler.addIndividual(*lGPIndividual, lContext.getGeneration(), lContext.getDemeIndex(), lIndividual- ioDeme.begin());
	}
	std::ostringstream lLibName;
	lLibName << "g" << lContext.getGeneration() << "_d" << lContext.getDemeIndex();
	lPathLib= lSharedLibCompiler.compile(lLibName.str());

    // Update register with the path of the newly compiled library.
    lContext.getSystem().getRegister().modifyEntry("icu.compiler.lib-path", new String(lPathLib));

    Beagle_StackTraceEndM("void SharedLibCompileOp::operate(Deme& ioDeme, Context& ioContext)");
}
Exemplo n.º 2
0
/*!
 *  \brief Expand modules in trees of actual population.
 *  \param ioDeme Deme to apply operation.
 *  \param ioContext Evolutionary context.
 */
void GP::ModuleExpandOp::operate(Beagle::Deme& ioDeme, Beagle::Context& ioContext)
{
    Beagle_StackTraceBeginM();
    Beagle_LogTraceM(
        ioContext.getSystem().getLogger(),
        "EMA", "GP::ModuleExpandOp",
        std::string("Expanding modules of the ")+
        uint2ordinal(ioContext.getDemeIndex()+1)+" deme"
    );
    if(mExpandProba->getWrappedValue()==0.0) return;

    Beagle_LogVerboseM(
        ioContext.getSystem().getLogger(),
        "EMA", "GP::ModuleExpandOp",
        std::string("Expanding modules with probability ")+
        dbl2str(mExpandProba->getWrappedValue())
    );

    GP::Context& lGPContext = castObjectT<GP::Context&>(ioContext);
    GP::Individual::Handle lOldIndividualHandle = lGPContext.getIndividualHandle();
    unsigned int lOldIndividualIndex = lGPContext.getIndividualIndex();
    GP::Tree::Handle lOldGenotypeHandle = lGPContext.getGenotypeHandle();
    unsigned int lOldGenotypeIndex = lGPContext.getGenotypeIndex();
    const std::string lModuleName = mModulePrimitName->getWrappedValue();
    for(unsigned int i=0; i<ioDeme.size(); i++) {
        for(unsigned int j=0; j<ioDeme[i]->size(); ++j) {
            GP::Tree& lTree = castObjectT<GP::Tree&>(*(*ioDeme[i])[j]);
            for(unsigned int k=0; k<lTree.size(); ++k) {
                if(lTree[k].mPrimitive->getName() == lModuleName) {
                    if(ioContext.getSystem().getRandomizer().rollUniform() <= mExpandProba->getWrappedValue()) {
                        lGPContext.setIndividualHandle(castHandleT<GP::Individual>(ioDeme[i]));
                        lGPContext.setIndividualIndex(i);
                        lGPContext.setGenotypeHandle(castHandleT<GP::Tree>((*ioDeme[i])[j]));
                        lGPContext.setGenotypeIndex(j);
                        Beagle_LogVerboseM(
                            ioContext.getSystem().getLogger(),
                            "expand", "ExpandOp",
                            std::string("Expanding the ") +uint2ordinal(i+1)+" individual"
                        );
                        expand(k, lTree, lGPContext);
                    }
                }
            }
        }
    }
    lGPContext.setGenotypeHandle(lOldGenotypeHandle);
    lGPContext.setGenotypeIndex(lOldGenotypeIndex);
    lGPContext.setIndividualHandle(lOldIndividualHandle);
    lGPContext.setIndividualIndex(lOldIndividualIndex);

    Beagle_LogObjectDebugM(
        ioContext.getSystem().getLogger(),
        "EMA", "GP::ModuleExpandOp",
        *(ioContext.getSystem().getComponent("ModuleVector"))
    );
    Beagle_StackTraceEndM();
}
/*!
 *  \brief Check if the evolution must terminate.
 *  \param inDeme Actual deme of the evolution.
 *  \param ioContext Actual evolution context.
 *  \return True if the ending criterion is reached, false if not.
 */
bool GP::TermMaxHitsOp::terminate(const Beagle::Deme& inDeme, Beagle::Context& ioContext)
{
	Beagle_StackTraceBeginM();
	if(mMaxHits->getWrappedValue() == 0) return false;
	for(unsigned int i=0; i<inDeme.size(); i++) {
		const GP::FitnessKoza::Handle lFitness =
		    castHandleT<const GP::FitnessKoza>(inDeme[i]->getFitness());
		if(mMaxHits->getWrappedValue() <= lFitness->getHits()) {
			Beagle_LogInfoM(
			    ioContext.getSystem().getLogger(),
			    "termination", "Beagle::GP::TermMaxHitsOp",
			    std::string("Maximum number of hits (") +
			    uint2str(mMaxHits->getWrappedValue()) +
			    std::string(") termination criterion reached")
			);
			Beagle_LogInfoM(
			    ioContext.getSystem().getLogger(),
			    "termination", "Beagle::GP::TermMaxHitsOp",
			    std::string("The ")+uint2ordinal(i+1) +
			    std::string(" individual of the deme has ") +
			    uint2str(lFitness->getHits())+std::string(" hits")
			);
			ioContext.setTerminationSuccessful();
			return true;
		}
	}
	Beagle_LogTraceM(
	    ioContext.getSystem().getLogger(),
	    "termination", "Beagle::GP::TermMaxHitsOp",
	    std::string("Maximum number of hits (") +
	    uint2str(mMaxHits->getWrappedValue()) +
	    std::string(") termination criterion not reached")
	);
	return false;
	Beagle_StackTraceEndM("bool GP::TermMaxHitsOp::terminate(const Beagle::Deme& inDeme, Beagle::Context& ioContext)");
}
Exemplo n.º 4
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 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 STGP::MutationSwapConstrainedOp::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;

	unsigned int lNbNodes = 0;
	for(unsigned int i=0; i<lIndividual.size(); i++) lNbNodes += lIndividual[i]->size();
	if(lNbNodes == 0) return false;
	unsigned int lChoosenNode = lContext.getSystem().getRandomizer().rollInteger(0, lNbNodes-1);
	unsigned int lChoosenTree = 0;
	for(; (lChoosenTree+1)<lIndividual.size(); lChoosenTree++) {
		if(lChoosenNode < lIndividual[lChoosenTree]->size()) break;
		else lChoosenNode -= lIndividual[lChoosenTree]->size();
	}
	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(),
	    "Individual before constrained GP tree swap mutation"
	);
	Beagle_LogDebugM(
	    ioContext.getSystem().getLogger(),
	    ioIndividual
	);

	if(lTree.size() > 1) {
		bool lTypeNode = (lContext.getSystem().getRandomizer().rollUniform(0., 1.) < lDistrProba);
		while((lTree[lChoosenNode].mPrimitive->getNumberArguments() != 0) != lTypeNode) {
			lChoosenNode = lContext.getSystem().getRandomizer().rollInteger(0, lTree.size()-1);
		}
	}
	GP::Primitive::Handle lOriginalPrimitive = lTree[lChoosenNode].mPrimitive;

	Beagle_LogVerboseM(
	    ioContext.getSystem().getLogger(),
	    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) {
		GP::Primitive::Handle lChoosenPrimitive = lPrimitiveSet.select(lNbArgsPrimit, lContext);
		if(lChoosenPrimitive==NULL) break;

		lTree[lChoosenNode].mPrimitive = lChoosenPrimitive->giveReference(lNbArgsPrimit, lContext);

		Beagle_LogVerboseM(
		    ioContext.getSystem().getLogger(),
		    std::string("Trying the primitive '")+lChoosenPrimitive->getName()+
		    std::string("'")
		);

		if(lTree.validateSubTree(lChoosenNode, lContext)) {
			lMutationDone = true;
			Beagle_LogVerboseM(
			    ioContext.getSystem().getLogger(),
			    "Constrained GP tree swap mutation valid"
			);
			break;
		} else {
			lTree[lChoosenNode].mPrimitive = lOriginalPrimitive;
			Beagle_LogVerboseM(
			    ioContext.getSystem().getLogger(),
			    "Constrained GP tree swap mutation invalid"
			);
		}
	}

	lContext.setGenotypeHandle(lOldTreeHandle);
	lContext.setGenotypeIndex(lOldTreeIndex);

	if(lMutationDone) {
		Beagle_LogDebugM(
		    ioContext.getSystem().getLogger(),
		    "Individual after constrained GP swap mutation"
		);
		Beagle_LogDebugM(
		    ioContext.getSystem().getLogger(),
		    ioIndividual
		);
	} else {
		Beagle_LogVerboseM(
		    ioContext.getSystem().getLogger(),
		    "Unable to swap mutate the constrained individual"
		);
	}

	return lMutationDone;
	Beagle_StackTraceEndM();
}
bool Beagle::GP::MutationEphemeralOpT<T>::mutate(Beagle::Individual& ioIndividual,
        Beagle::Context& ioContext)
{
	Beagle_StackTraceBeginM();
	Beagle_LogDetailedM(
	    ioContext.getSystem().getLogger(),
	    "mutation", "Beagle::GP::MutationEphemeralOpT",
	    std::string("Mutating ")+uint2ordinal(ioContext.getGenotypeIndex()+1)+
	    std::string(" individual with GP::MutationEphemeralOpT")
	);

	GP::Individual& lIndividual = castObjectT<GP::Individual&>(ioIndividual);
	GP::Context& lContext = castObjectT<GP::Context&>(ioContext);

	// Get index of potential primitives with parameters that can be selected for mutation.
	std::vector< std::pair<unsigned int,unsigned int> > lPotentialParam;
	for(unsigned int i=0; i<lIndividual.size(); ++i) {
		GP::Tree& lTree = *lIndividual[i];
		for(unsigned int j=0; j<lTree.size(); ++j) {
			if(lTree[j].mPrimitive->getName() == *mEphemeralName) {
				lPotentialParam.push_back(std::make_pair(i,j));
			}
		}
	}

	// Return if there is not potential parameters.
	if(lPotentialParam.empty()) return false;

	// Mutating a primitive
	Beagle_LogDebugM(
	    ioContext.getSystem().getLogger(),
	    "mutation",
	    "Beagle::GP::MutationEphemeralOpT",
	    "Individual before GP parameters mutation"
	);
	Beagle_LogObjectDebugM(
	    ioContext.getSystem().getLogger(),
	    "mutation",
	    "Beagle::GP::MutationEphemeralOpT",
	    ioIndividual
	);

	// Store original context values
	unsigned int lOldGenotypeIndex = lContext.getGenotypeIndex();
	GP::Tree::Handle lOldGenotypeHandle = lContext.getGenotypeHandle();

	// Get reference to primitive to mutate and other objects.
	const unsigned int lSelectedParam =
	    lContext.getSystem().getRandomizer().rollInteger(0,lPotentialParam.size()-1);
	GP::Tree::Handle lSelectedTree = lIndividual[lPotentialParam[lSelectedParam].first];
	lContext.setGenotypeIndex(lPotentialParam[lSelectedParam].first);
	lContext.setGenotypeHandle(lSelectedTree);
	Beagle_LogVerboseM(
	    ioContext.getSystem().getLogger(),
	    "mutation", "Beagle::GP::MutationEphemeralOpT",
	    std::string("Mutating the parameter of the ")+
	    uint2ordinal(lPotentialParam[lSelectedParam].second+1)+
	    std::string(" node in the ")+uint2ordinal(lPotentialParam[lSelectedParam].first+1)+
	    std::string(" tree")
	);

	// Mutate parameter value.
	GP::Primitive::Handle lSelectedPrimit =
	    (*lSelectedTree)[lPotentialParam[lSelectedParam].second].mPrimitive;
	typename GP::EphemeralT<T>::Handle lSelectedEphemeral =
	    castHandleT<typename GP::EphemeralT<T> >(lSelectedPrimit);
	GP::Primitive::Handle lGeneratedPrimit =
	    lSelectedEphemeral->generate(mEphemeralName->getWrappedValue(), lContext);
	(*lSelectedTree)[lPotentialParam[lSelectedParam].second].mPrimitive = lGeneratedPrimit;

	Beagle_LogVerboseM(
	    ioContext.getSystem().getLogger(),
	    "mutation", "Beagle::GP::MutationEphemeralOpT",
	    std::string("Changing the ephemeral from ")+lSelectedPrimit->serialize()+
	    std::string(" to ")+lGeneratedPrimit->serialize()
	);

	// Restore original context values
	lContext.setGenotypeIndex(lOldGenotypeIndex);
	lContext.setGenotypeHandle(lOldGenotypeHandle);

	Beagle_LogDebugM(
	    ioContext.getSystem().getLogger(),
	    "mutation",
	    "Beagle::GP::MutationEphemeralOpT",
	    "Individual after GP parameters mutation"
	);
	Beagle_LogObjectDebugM(
	    ioContext.getSystem().getLogger(),
	    "mutation",
	    "Beagle::GP::MutationEphemeralOpT",
	    ioIndividual
	);

	return true;
	Beagle_StackTraceEndM("bool GP::MutationEphemeralOpT<T>::mutate(Individual& ioIndividual, Context& ioContext)");
}
/*!
 *  \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)");
}
Exemplo n.º 8
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();
}
/*!
 *  \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.º 10
0
/*!
 *  \brief Initialize the trees of an individual.
 *  \param outIndividual Individual to initialize.
 *  \param ioContext Evolution context.
 *  \throw Beagle::RunTimeException If the min/max depths are incorrectly set.
 */
void GP::InitializationOp::initIndividual(Beagle::Individual& outIndividual,
        Beagle::Context& ioContext)
{
	Beagle_StackTraceBeginM();
#ifndef BEAGLE_NDEBUG
	if (mMinTreeDepth==NULL || mMaxTreeDepth==NULL)
		throw Beagle_RunTimeExceptionM(std::string("GP::InitializationOp has not been initialized.").
		                               append(" Consider the GP::InitializationOp::registerParams() method."));
	if(*mMinTreeDepth > *mMaxTreeDepth) {
		std::string lMessage = "GP::InitializationOp::initIndividual: Minimum tree depth is superior ";
		lMessage += "to the maximum tree depth. Could not initialize the individuals!";
		throw Beagle::ValidationException(lMessage);
	}
#endif // BEAGLE_NDEBUG
	Beagle_ValidateParameterM(mMinTreeDepth->getWrappedValue()>0,"gp.init.mindepth",">0");

	GP::Individual& lIndividual = castObjectT<GP::Individual&>(outIndividual);
	GP::Context& lContext = castObjectT<GP::Context&>(ioContext);

	GP::PrimitiveSuperSet::Handle lSuperSet =
	    castHandleT<GP::PrimitiveSuperSet>(ioContext.getSystem().getComponent("GP-PrimitiveSuperSet"));
	if(lSuperSet == NULL) {
		throw Beagle_RunTimeExceptionM("There should be a GP::PrimitiveSuperSet component in the system");
	}
	const unsigned int lPrimitiveSuperSetSize = lSuperSet->size();
	const Factory& lFactory = ioContext.getSystem().getFactory();
#ifndef BEAGLE_NDEBUG
	if(lPrimitiveSuperSetSize == 0)
		throw Beagle_RunTimeExceptionM(std::string("GP::InitializationOp::initIndividual(): There ").
		                               append(" are no PrimitiveSets in the PrimitiveSuperSet.  There needs to be at least one").
		                               append(" PrimitiveSet. See the examples that are included with Beagle to learn how").
		                               append(" to create a PrimitiveSet, add Primitives to it, and then construct a System based").
		                               append(" on the PrimitiveSet."));
#endif // BEAGLE_NDEBUG

	// Choose randomly the number of individuals in tree
	const unsigned int lMaxDepth   = mMaxTreeDepth->getWrappedValue();
	const unsigned int lMinDepth   = mMinTreeDepth->getWrappedValue();
	const unsigned int lMaxNbTrees = mMaxNumberTrees->getWrappedValue();
	const unsigned int lMinNbTrees = mMinNumberTrees->getWrappedValue();
	Beagle_AssertM(lMaxNbTrees >= lMinNbTrees);
	const unsigned int lNbTrees =
	    ioContext.getSystem().getRandomizer().rollInteger(lMinNbTrees,lMaxNbTrees);
	Genotype::Alloc::Handle lGenotypeAlloc =
		castHandleT<Genotype::Alloc>(lFactory.getConceptAllocator("Genotype"));
	lIndividual.clear();
	for(unsigned int i=0; i<lNbTrees; ++i) {
		lIndividual.push_back(castHandleT<Genotype>(lGenotypeAlloc->allocate()));
	}
	GP::Tree::Handle lOldTreeHandle = lContext.getGenotypeHandle();
	unsigned int lOldTreeIndex = lContext.getGenotypeIndex();
	for(unsigned int i=0; i<lIndividual.size(); ++i) {
		if(i<lPrimitiveSuperSetSize) lIndividual[i]->setPrimitiveSetIndex(i);
		else lIndividual[i]->setPrimitiveSetIndex(lPrimitiveSuperSetSize-1);
		const unsigned int lMaxArgs =
		    (i<mMaxTreeArgs->size()) ? (*mMaxTreeArgs)[i] : mMaxTreeArgs->back();
		const unsigned int lMinArgs =
		    (i<mMinTreeArgs->size()) ? (*mMinTreeArgs)[i] : mMinTreeArgs->back();
		Beagle_AssertM(lMaxArgs >= lMinArgs);
		const unsigned int lNbArgs =
		    ioContext.getSystem().getRandomizer().rollInteger(lMinArgs,lMaxArgs);
		lIndividual[i]->setNumberArguments(lNbArgs);
	}
	for(unsigned int i=0; i<lIndividual.size(); ++i) {
		lContext.setGenotypeHandle(lIndividual[i]);
		lContext.setGenotypeIndex(i);
		const unsigned int lTreeDepth =
		    lContext.getSystem().getRandomizer().rollInteger(lMinDepth,lMaxDepth);
		lContext.emptyCallStack();
		lIndividual[i]->clear();
		initTree(*lIndividual[i], lMinDepth, lTreeDepth, lContext);
	}

	Beagle_LogDebugM(
	    ioContext.getSystem().getLogger(),
	    "initialization", "Beagle::GP::InitializationOp",
	    std::string("Initialized individual:")
	);
	Beagle_LogObjectDebugM(
	    ioContext.getSystem().getLogger(),
	    "initialization", "Beagle::GP::InitializationOp",
	    lIndividual
	);

	lContext.setGenotypeIndex(lOldTreeIndex);
	lContext.setGenotypeHandle(lOldTreeHandle);
	Beagle_StackTraceEndM();
}
/*!
 *  \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 STGP::MutationStandardConstrainedOp::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();

	unsigned int lNbNodes = 0;
	for(unsigned int i=0; i<lIndividual.size(); i++) lNbNodes += lIndividual[i]->size();
	if(lNbNodes == 0) return false;
	unsigned int lChoosenNode = lContext.getSystem().getRandomizer().rollInteger(0, lNbNodes-1);
	unsigned int lChoosenTree = 0;
	for(; (lChoosenTree+1)<lIndividual.size(); lChoosenTree++) {
		if(lChoosenNode < lIndividual[lChoosenTree]->size()) break;
		else lChoosenNode -= lIndividual[lChoosenTree]->size();
	}

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

	unsigned int lOldGenotypeIndex = lContext.getGenotypeIndex();
	GP::Tree::Handle lOldGenotypeHandle = lContext.getGenotypeHandle();

	Beagle_LogDebugM(
	    ioContext.getSystem().getLogger(),
	    "Individual before GP standard mutation"
	);
	Beagle_LogDebugM(
	    ioContext.getSystem().getLogger(),
	    ioIndividual
	);

	GP::Tree::Handle lActualTree = lIndividual[lChoosenTree];
	GP::Tree::Handle lNewTree    = castHandleT<GP::Tree>(lTreeAlloc->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;
	for(; lAttempt < mNumberAttempts->getWrappedValue(); lAttempt++) {
		if(mInitOp->initTree(*lNewTree, 1, lMaxSubTreeDepth, lContext) != 0) break;
	}
	if(lAttempt == mNumberAttempts->getWrappedValue()) {
		lIndividual[lChoosenTree] = lActualTree;
		lContext.setGenotypeIndex(lOldGenotypeIndex);
		lContext.setGenotypeHandle(lOldGenotypeHandle);
		Beagle_LogVerboseM(
		    ioContext.getSystem().getLogger(),
		    "Unable to GP standard mutate the individual"
		);
		return false;
	}

	Beagle_LogVerboseM(
	    ioContext.getSystem().getLogger(),
	    std::string("GP standard mutate the ")+uint2ordinal(lChoosenNode+1)+
	    std::string(" node 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(),
	    "Individual after GP standard mutation"
	);
	Beagle_LogDebugM(
	    ioContext.getSystem().getLogger(),
	    ioIndividual
	);

	return true;
	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;
}
Exemplo n.º 13
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 Insert mutate a GP individual.
 *  \param ioIndividual GP individual to mutate.
 *  \param ioContext Context of the evolution.
 *  \return True if the individual is effectively mutated, false if not.
 */
bool GP::MutationInsertConstrainedOp::mutate(Beagle::Individual& ioIndividual, Beagle::Context& ioContext)
{
	Beagle_StackTraceBeginM();

	Beagle_LogDetailedM(
	    ioContext.getSystem().getLogger(),
	    "mutation", "Beagle::GP::MutationInsertConstrainedOp",
	    std::string("Mutating individual with GP::MutationInsertConstrainedOp")
	);

	GP::Individual& lIndividual = castObjectT<GP::Individual&>(ioIndividual);
	GP::Context& lContext = castObjectT<GP::Context&>(ioContext);
	const unsigned int lMaxAttempts = mNumberAttempts->getWrappedValue();
	const unsigned int lMaxTreeDepth = mMaxTreeDepth->getWrappedValue();

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

	// Store original context values
	const unsigned int lOldGenotypeIndex = lContext.getGenotypeIndex();
	const GP::Tree::Handle lOldGenotypeHandle = lContext.getGenotypeHandle();

	Beagle_LogDebugM(
	    ioContext.getSystem().getLogger(),
	    "mutation", "Beagle::GP::MutationInsertConstrainedOp",
	    "Individual before constrained GP insert mutation"
	);
	Beagle_LogObjectDebugM(
	    ioContext.getSystem().getLogger(),
	    "mutation", "Beagle::GP::MutationInsertConstrainedOp",
	    ioIndividual
	);

	// Mutation attempts loop
	for(unsigned int i=0; i<lMaxAttempts; ++i) {

		// Choose tree and node to mutate
		const unsigned int lChosenTree = lIndividual.chooseRandomTree(lContext);
		const unsigned int lChosenNodeIndex = lIndividual.chooseRandomNode(lChosenTree, lContext);
		GP::Tree::Handle lOriginalTree = lIndividual[lChosenTree];

		// Compute depth of tree generated by mutation
		lContext.setGenotypeIndex(lChosenTree);
		lContext.setGenotypeHandle(lOriginalTree);
		lContext.emptyCallStack();
		lOriginalTree->setContextToNode(lChosenNodeIndex, lContext);
		const unsigned int lMutationDepth =
		    lContext.getCallStackSize() + lOriginalTree->getTreeDepth(lChosenNodeIndex);

		// Check that mutation will not generate a tree deeper than the maximum allowed depth
		if(lMutationDepth > lMaxTreeDepth) {
			Beagle_LogDebugM(
			    ioContext.getSystem().getLogger(),
			    "mutation", "Beagle::GP::MutationInsertConstrainedOp",
			    std::string("Constrained insert mutation attempt failed as the generated tree will exceed ")+
			    std::string("maximum allowed tree depth")
			);
			continue;
		}

		// Create new tree
		Beagle_LogDebugM(
		    ioContext.getSystem().getLogger(),
		    "mutation", "Beagle::GP::MutationInsertConstrainedOp",
		    std::string("Creating new tree")
		);
		GP::Tree::Handle lNewTree = castHandleT<GP::Tree>(lTreeAlloc->allocate());
		lNewTree->setPrimitiveSetIndex(lOriginalTree->getPrimitiveSetIndex());
		lNewTree->setNumberArguments(lOriginalTree->getNumberArguments());

		// Replace original tree with new tree
		lIndividual[lChosenTree] = lNewTree;
		lContext.setGenotypeHandle(lNewTree);

		// Copy unchanged part of original tree into new tree
		Beagle_LogDebugM(
		    ioContext.getSystem().getLogger(),
		    "mutation", "Beagle::GP::MutationInsertConstrainedOp",
		    std::string("Copying unchanged part of original tree to new tree")
		);
		lNewTree->insert(lNewTree->end(),
		                 lOriginalTree->begin(),
		                 lOriginalTree->begin()+lChosenNodeIndex);
		Beagle_AssertM(lNewTree->size() == lChosenNodeIndex);

		// Generate new branch primitive to insert.
		GP::PrimitiveSet& lPrimitiveSet = lNewTree->getPrimitiveSet(lContext);
		Primitive::Handle lBranchInserted = lPrimitiveSet.select(GP::Primitive::eBranch, lContext);
		if(lBranchInserted==NULL) {
			Beagle_LogDebugM(
			    ioContext.getSystem().getLogger(),
			    "mutation", "Beagle::GP::MutationInsertConstrainedOp",
			    std::string("Constrained insert mutation attempt failed as it seems impossible ")+
			    std::string("to select a branch primitive in the actual context")
			);
			lIndividual[lChosenTree] = lOriginalTree;
			lContext.setGenotypeHandle(lOriginalTree);
			continue;
		}
		Beagle_LogDebugM(
		    ioContext.getSystem().getLogger(),
		    "mutation", "Beagle::GP::MutationInsertConstrainedOp",
		    std::string("Branch primitive to be inserted by mutation is primitive '")+
		    lBranchInserted->getName()+std::string("'")
		);

		// Insert new branch
		lBranchInserted = lBranchInserted->giveReference(GP::Primitive::eBranch, lContext);
		lNewTree->push_back(Node(lBranchInserted,1));
		if(lBranchInserted->validate(lContext) == false) {
			Beagle_LogDebugM(
			    ioContext.getSystem().getLogger(),
			    "mutation", "Beagle::GP::MutationInsertConstrainedOp",
			    std::string("Constrained insert mutation attempt failed as the selected ")+
			    std::string("branch doesn't match the constraints")
			);
			lIndividual[lChosenTree] = lOriginalTree;
			lContext.setGenotypeHandle(lOriginalTree);
			continue;
		}
		const unsigned int lNbArgsInsertedBranch = lBranchInserted->getNumberArguments();
		Beagle_AssertM(lNbArgsInsertedBranch != 0);
		const unsigned int lSubtreeArgIndex =
		    lContext.getSystem().getRandomizer().rollInteger(0, lNbArgsInsertedBranch-1);
		Beagle_AssertM(lSubtreeArgIndex < lNbArgsInsertedBranch);
		const unsigned int lSubtreeSize = (*lOriginalTree)[lChosenNodeIndex].mSubTreeSize;

		// Generate inserted node subtrees
		bool lArgsGenFailed = false;
		for(unsigned int j=0; j<lNbArgsInsertedBranch; ++j) {
			if(j == lSubtreeArgIndex) {
				const unsigned int lSubtreeIndex = lNewTree->size();
				lNewTree->insert(lNewTree->end(),
				                 lOriginalTree->begin()+lChosenNodeIndex,
				                 lOriginalTree->begin()+lChosenNodeIndex+lSubtreeSize);
				lContext.pushCallStack(lSubtreeIndex);
				if(lNewTree->validateSubTree(lSubtreeIndex, lContext) == false) {
					lArgsGenFailed = true;
					break;
				}
				lContext.popCallStack();
				(*lNewTree)[lChosenNodeIndex].mSubTreeSize += lSubtreeSize;
			} else {
				Primitive::Handle lArgInserted = lPrimitiveSet.select(GP::Primitive::eTerminal, lContext);
				if(lArgInserted == NULL) {
					lArgsGenFailed = true;
					break;
				}
				lArgInserted = lArgInserted->giveReference(GP::Primitive::eTerminal, lContext);
				const unsigned int lSubtreeIndex = lNewTree->size();
				lNewTree->push_back(Node(lArgInserted,1));
				lContext.pushCallStack(lSubtreeIndex);
				if(lArgInserted->validate(lContext) == false) {
					lArgsGenFailed = true;
					break;
				}
				lContext.popCallStack();
				++(*lNewTree)[lChosenNodeIndex].mSubTreeSize;
			}
		}
		if(lArgsGenFailed) {
			Beagle_LogDebugM(
			    ioContext.getSystem().getLogger(),
			    "mutation", "Beagle::GP::MutationInsertConstrainedOp",
			    std::string("Constrained insert mutation attempt failed as it seems impossible ")+
			    std::string("to select a terminal primitive under the inserted branch in the actual context")
			);
			lIndividual[lChosenTree] = lOriginalTree;
			lContext.setGenotypeHandle(lOriginalTree);
			continue;
		}

		// Complete new tree with rest of original tree
		Beagle_AssertM(lOriginalTree->size() >= (lChosenNodeIndex+lSubtreeSize));
		lNewTree->insert(lNewTree->end(),
		                 lOriginalTree->begin()+lChosenNodeIndex+lSubtreeSize,
		                 lOriginalTree->end());
		Beagle_AssertM(lNewTree->size() == (lOriginalTree->size()+lNbArgsInsertedBranch));

		// Correct subtree size data and terminate mutation process
		Beagle_LogDebugM(
		    ioContext.getSystem().getLogger(),
		    "mutation", "Beagle::GP::MutationInsertConstrainedOp",
		    std::string("Correcting the 'mSubTreeSize' fields of tree")
		);
		lContext.popCallStack();
		for(unsigned int j=0; j<lContext.getCallStackSize(); ++j) {
			(*lNewTree)[lContext[j]].mSubTreeSize += lNbArgsInsertedBranch;
		}

		// Mutation successful, log messages and return
		std::ostringstream lOSS;
		lOSS << "Successfully inserted a new node at index " << lChosenNodeIndex;
		lOSS << " of the " << uint2ordinal(lChosenTree) << " tree of the actual individual";
		Beagle_LogTraceM(
		    ioContext.getSystem().getLogger(),
		    "mutation",
		    "Beagle::GP::MutationInsertConstrainedOp",
		    lOSS.str()
		);
		Beagle_LogDebugM(
		    ioContext.getSystem().getLogger(),
		    "mutation",
		    "Beagle::GP::MutationInsertConstrainedOp",
		    "Individual after constrained GP insert mutation"
		);
		Beagle_LogObjectDebugM(
		    ioContext.getSystem().getLogger(),
		    "mutation",
		    "Beagle::GP::MutationInsertConstrainedOp",
		    ioIndividual
		);
		lContext.emptyCallStack();
		lContext.setGenotypeIndex(lOldGenotypeIndex);
		lContext.setGenotypeHandle(lOldGenotypeHandle);
		return true;
	}

	// Insert mutation failed, return without mutating the individual
	lContext.emptyCallStack();
	lContext.setGenotypeIndex(lOldGenotypeIndex);
	lContext.setGenotypeHandle(lOldGenotypeHandle);
	Beagle_LogTraceM(
	    ioContext.getSystem().getLogger(),
	    "mutation", "Beagle::GP::MutationInsertConstrainedOp",
	    std::string("All constrained insert mutation attempts failed; ")+
	    std::string("resuming from mutation without modifying the individual")
	);
	return false;

	Beagle_StackTraceEndM("bool GP::MutationInsertConstrainedOp::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)");
}
Exemplo n.º 16
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 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)");
}
/*!
 *  \brief Swap mutate a 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::MutationSwapOp::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();

	// Store original values.
	GP::Tree::Handle lOldTreeHandle = lContext.getGenotypeHandle();
	unsigned int lOldTreeIndex = lContext.getGenotypeIndex();

	// Select the tree to mutate
	unsigned int lNbNodes = 0;
	for(unsigned int i=0; i<lIndividual.size(); i++) lNbNodes += lIndividual[i]->size();
	if(lNbNodes == 0) return false;
	unsigned int lChosenNode = lContext.getSystem().getRandomizer().rollInteger(0, lNbNodes-1);
	unsigned int lChosenTree = 0;
	for(; (lChosenTree+1)<lIndividual.size(); lChosenTree++) {
		if(lChosenNode < lIndividual[lChosenTree]->size()) break;
		else lChosenNode -= lIndividual[lChosenTree]->size();
	}
	GP::Tree& lTree = *lIndividual[lChosenTree];
	if(lTree.size() == 0) return false;

	// Store the new values
	lContext.setGenotypeHandle(lIndividual[lChosenTree]);
	lContext.setGenotypeIndex(lChosenTree);

	Beagle_LogDebugM(
	    ioContext.getSystem().getLogger(),
	    "mutation",
	    "Beagle::GP::MutationSwapOp",
	    "Individual before GP swap mutation"
	);
	Beagle_LogObjectDebugM(
	    ioContext.getSystem().getLogger(),
	    "mutation",
	    "Beagle::GP::MutationSwapOp",
	    ioIndividual
	);

	// Choose the node to mutate.
	if(lTree.size() > 1) {
		bool lTypeNode = (lContext.getSystem().getRandomizer().rollUniform(0., 1.) < lDistrProba);
		while((lTree[lChosenNode].mPrimitive->getNumberArguments() != 0) != lTypeNode) {
			lChosenNode = lContext.getSystem().getRandomizer().rollInteger(0, lTree.size()-1);
		}
	}
	Primitive::Handle lOriginalPrimitive = lTree[lChosenNode].mPrimitive;

	Beagle_LogVerboseM(
	    ioContext.getSystem().getLogger(),
	    "mutation", "Beagle::GP::MutationSwapOp",
	    std::string("Swap mutating the ")+uint2ordinal(lChosenNode+1)+
	    std::string(" node (primitive: '")+lOriginalPrimitive->getName()+
	    std::string("' nb args: ")+uint2str(lOriginalPrimitive->getNumberArguments())+
	    std::string(") of the ")+uint2ordinal(lChosenTree+1)+std::string(" tree")
	);

	GP::PrimitiveSet& lPrimitiveSet = lTree.getPrimitiveSet(lContext);
	unsigned int lNbArgsPrimit = lTree[lChosenNode].mPrimitive->getNumberArguments();

	// Select primitive to replace choosen one.
	Primitive::Handle lChosenPrimitive = lPrimitiveSet.select(lNbArgsPrimit, lContext);
	if (lChosenPrimitive==NULL) {
		Beagle_LogVerboseM(
		    ioContext.getSystem().getLogger(),
		    "mutation", "Beagle::GP::MutationSwapOp",
		    std::string("Swap mutation failed because no primitive could be found that had ")+
		    uint2str(lNbArgsPrimit)+std::string(" arguments")
		);
		return false;
	} else {
		Beagle_LogDebugM(
		    ioContext.getSystem().getLogger(),
		    "mutation", "Beagle::GP::MutationSwapOp",
		    std::string("Swap mutation chose primitive '")+lChosenPrimitive->getName()+std::string("'")
		);
	}

	// Replace choose primitive.
	lTree[lChosenNode].mPrimitive = lChosenPrimitive->giveReference(lNbArgsPrimit, lContext);

	// Restore the original values.
	lContext.setGenotypeHandle(lOldTreeHandle);
	lContext.setGenotypeIndex(lOldTreeIndex);

	Beagle_LogDebugM(
	    ioContext.getSystem().getLogger(),
	    "mutation", "Beagle::GP::MutationSwapOp",
	    "Individual after GP swap mutation"
	);
	Beagle_LogObjectDebugM(
	    ioContext.getSystem().getLogger(),
	    "mutation",
	    "Beagle::GP::MutationSwapOp",
	    ioIndividual
	);

	return true;
	Beagle_StackTraceEndM("bool GP::MutationSwapOp::mutate(Beagle::Individual& ioIndividual, Beagle::Context& ioContext)");
}