/*!
 *  \brief Initialize a GP sub-tree of a specified depth using the "grow" approach.
 *  \param ioTree Tree containing the sub-tree to initialize.
 *  \param inMinDepth Minimal depth of the sub-tree to initialize.
 *  \param inMaxDepth Maximal depth of the sub-tree to initialize.
 *  \param ioContext Evolutionary context.
 *  \return Generated sub-tree size.
 */
unsigned int GP::InitGrowOp::initSubTreeGrow(GP::Tree& ioTree,
        unsigned int inMinDepth,
        unsigned int inMaxDepth,
        GP::Context& ioContext) const
{
	Beagle_StackTraceBeginM();
	Beagle_AssertM(inMaxDepth >= inMinDepth);
	Beagle_AssertM(inMinDepth>0);
	GP::PrimitiveSet& lPrimitSet = ioTree.getPrimitiveSet(ioContext);
	GP::Primitive::Handle lPrimit = NULL;
	if(inMinDepth > 1) {
		lPrimit = lPrimitSet.select(GP::Primitive::eBranch, ioContext);
		if(!lPrimit) {
			std::string lMessage = "There is no branch (primitive with arguments) in the ";
			lMessage += uint2ordinal(ioContext.getGenotypeIndex()+1);
			lMessage += " primitive set!";
			throw Beagle_RunTimeExceptionM(lMessage);
		}
		lPrimit = lPrimit->giveReference(GP::Primitive::eBranch, ioContext);
	} else if(inMaxDepth == 1) {
		lPrimit = lPrimitSet.select(GP::Primitive::eTerminal, ioContext);
		if(!lPrimit) {
			std::string lMessage = "There is no leaf (primitive without argument) in the ";
			lMessage += uint2ordinal(ioContext.getGenotypeIndex()+1);
			lMessage += " primitive set!";
			throw Beagle_RunTimeExceptionM(lMessage);
		}
		lPrimit = lPrimit->giveReference(GP::Primitive::eTerminal, ioContext);
	} else {
		lPrimit = lPrimitSet.select(GP::Primitive::eAny, ioContext);
		if(!lPrimit) {
			std::string lMessage = "There is no primitive in the ";
			lMessage += uint2ordinal(ioContext.getGenotypeIndex()+1);
			lMessage += " primitive set!";
			throw Beagle_RunTimeExceptionM(lMessage);
		}
		lPrimit = lPrimit->giveReference(GP::Primitive::eAny, ioContext);
	}
	unsigned int lNodeIndex = ioTree.size();
	ioTree.push_back(GP::Node(lPrimit, 1));
	unsigned int lSubTreeSize = 1;
	unsigned int lMinDepth = (inMinDepth > 1) ? (inMinDepth-1) : 1;
	for(unsigned int i=0; i<ioTree[lNodeIndex].mPrimitive->getNumberArguments(); i++) {
		lSubTreeSize += initSubTreeGrow(ioTree, lMinDepth, inMaxDepth-1, ioContext);
	}
	ioTree[lNodeIndex].mSubTreeSize = lSubTreeSize;
	return lSubTreeSize;
	Beagle_StackTraceEndM("unsigned int GP::InitGrowOp::initSubTreeGrow(GP::Tree& ioTree, unsigned int inMinDepth, unsigned int inMaxDepth, GP::Context& ioContext) const");
}
예제 #2
0
/*!
 *  \brief Validate the GP individual.
 *  \param ioContext Evolutionary context.
 *  \return True if the GP individual is valid, false if not.
 */
bool GP::Individual::validate(GP::Context& ioContext)
{
	Beagle_StackTraceBeginM();
	bool lResult = true;

	Beagle_LogDetailedM(
	    ioContext.getSystem().getLogger(),
	    std::string("Validating ")+uint2ordinal(ioContext.getIndividualIndex()+1)+
	    std::string(" individual")
	);

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

	// Loop through each of the trees in the individual
	for (unsigned int i=0; i<size(); i++) {
		GP::Tree::Handle lTree = (*this)[i];
		if (lTree == NULL) {
			Beagle_LogVerboseM(
			    ioContext.getSystem().getLogger(),
			    std::string("Skipping ")+uint2ordinal(i+1)+std::string(" tree because it's NULL-valued")
			);
			continue;
		}

		Beagle_LogVerboseM(
		    ioContext.getSystem().getLogger(),
		    std::string("Validating ")+uint2ordinal(i+1)+std::string(" tree")
		);

		// Store the new values
		ioContext.setGenotypeHandle(lTree);
		ioContext.setGenotypeIndex(i);

		lTree->setContextToNode(0, ioContext);
		if(!lTree->validateSubTree(0, ioContext)) {
			Beagle_LogVerboseM(
			    ioContext.getSystem().getLogger(),
			    std::string("Validation of ")+uint2ordinal(i+1)+std::string(" tree failed.")
			);
			lResult = false;
			break;
		}
	}

	if(lResult) {
		Beagle_LogVerboseM(
		    ioContext.getSystem().getLogger(),
		    std::string("Individual passed validation testing.")
		);
	}

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

	return lResult;
	Beagle_StackTraceEndM();
}
void TreeSTag::removeNOP(Individual& inIndividual, GP::Context& ioContext) {
//	Beagle_LogDebugM(
//					 ioContext.getSystem().getLogger(),
//					 "individual", "TreeSTag",
//					 std::string("Individual before NOP removal: ")+inIndividual.serialize()
//					 );
	
	
	TreeSTag::Handle lTree = castHandleT<TreeSTag>((inIndividual)[0]);
	GP::Individual& lIndividual = castObjectT<GP::Individual&>(inIndividual);
	
	GP::Individual::Handle lOldIndividualHandle = ioContext.getIndividualHandle();
	unsigned int lOldGenotypeIndex = ioContext.getGenotypeIndex();
	GP::Tree::Handle lOldGenotypeHandle = ioContext.getGenotypeHandle();	
	
	ioContext.setIndividualHandle(&lIndividual);
	ioContext.setGenotypeIndex(0);
	ioContext.setGenotypeHandle(lIndividual[0]);
	
	ioContext.getCallStack().clear();
	removeNOPLoop(0,ioContext);
	
	ioContext.setIndividualHandle(lOldIndividualHandle);
	ioContext.setGenotypeIndex(lOldGenotypeIndex);
	ioContext.setGenotypeHandle(lOldGenotypeHandle);
	
//	Beagle_LogDebugM(
//					 ioContext.getSystem().getLogger(),
//					 "individual", "TreeSTag",
//					 std::string("Individual after NOP removal: ")+inIndividual.serialize()
//					 );
}
/*!
 *  \brief Initialize a tree.
 *  \param outTree Tree to initialize.
 *  \param inMinDepth Minimum depth of to make tree.
 *  \param inMaxDepth Maximum depth of to make tree.
 *  \param ioContext Evolution context.
 *  \return Size of newly initialized tree.
 */
unsigned int GP::InitGrowOp::initTree(GP::Tree& outTree,
                                      unsigned int inMinDepth,
                                      unsigned int inMaxDepth,
                                      GP::Context& ioContext) const
{
	Beagle_StackTraceBeginM();

	if (mKozaGrow->getWrappedValue()) {
		Beagle_LogVerboseM(
		    ioContext.getSystem().getLogger(),
		    "initialization", "Beagle::GP::InitGrowConstrainedOp",
		    "Setting the minimum depth to 2 (as per 'gp.init.kozagrow')"
		);
		inMinDepth=2;
	}

	Beagle_AssertM(inMaxDepth >= inMinDepth);
	Beagle_AssertM(inMinDepth>0);

	Beagle_LogVerboseM(
	    ioContext.getSystem().getLogger(),
	    "initialization", "Beagle::GP::InitGrowOp",
	    std::string("Using the \'grow\' method (with maximum depth ")+uint2str(inMaxDepth)+
	    std::string(" and minimum depth ")+uint2str(inMinDepth)+std::string(") to initialize the ")+
	    uint2ordinal(ioContext.getGenotypeIndex()+1)+std::string(" tree")
	);

	return initSubTreeGrow(outTree, inMinDepth, inMaxDepth, ioContext);
	Beagle_StackTraceEndM("unsigned int GP::InitGrowOp::initTree(GP::Tree &outTree, unsigned int inMinDepth, unsigned int inMaxDepth, GP::Context& ioContext) const");
}
/*!
 *  \brief Initialize a constrained GP tree of a specified depth using the "full" approach.
 *  \param outTree Tree to initialize.
 *  \param inMinDepth Minimum depth to make tree.
 *  \param inMaxDepth Maximum depth to make tree.
 *  \param ioContext Evolutionary context.
 */
unsigned int GP::InitFullConstrainedOp::initTree(GP::Tree& outTree,
        unsigned int inMinDepth,
        unsigned int inMaxDepth,
        GP::Context &ioContext) const
{
	Beagle_StackTraceBeginM();

	const unsigned int lDepth = inMaxDepth;
	Beagle_AssertM(lDepth>0);

	Beagle_LogVerboseM(
	    ioContext.getSystem().getLogger(),
	    "initialization", "Beagle::GP::InitFullConstrainedOp",
	    std::string("Using the constrained \'full\' method (with depth ")+
	    uint2str(lDepth)+std::string(") to initialize the ")+
	    uint2ordinal(ioContext.getGenotypeIndex()+1)+std::string(" tree.")
	);

	unsigned int lSubTreeSize;
	do {
		lSubTreeSize = initConstrainedSubTreeFull(outTree, lDepth, ioContext);
	} while (lSubTreeSize == 0);
	return lSubTreeSize;
	Beagle_StackTraceEndM("unsigned int GP::InitFullConstrainedOp::initTree(GP::Tree& outTree, unsigned int inMinDepth, unsigned int inMaxDepth, GP::Context &ioContext) const");
}
예제 #6
0
/*!
 *  \brief Invoke GP tree to execute as ADF.
 *  \param outResult Result of GP tree invocation
 *  \param ioTree Tree to invoke.
 *  \param ioContext Evolutionary context.
 */
void GP::Module::invoke(GP::Datum& outResult, GP::Tree::Handle ioTree, GP::Context& ioContext)
{
	Beagle_StackTraceBeginM();
	GP::Tree::Handle lOldGenotypeHandle = ioContext.getGenotypeHandle();
	unsigned int lOldGenotypeIndex = ioContext.getGenotypeIndex();
	ioContext.setGenotypeHandle(ioTree);
	ioContext.setGenotypeIndex(mIndex);
	ioContext.incrementNodesExecuted();
	ioContext.pushCallStack(0);
	Beagle_LogVerboseM(
	    ioContext.getSystem().getLogger(),
	    "EMA", "Beagle::GP::Module",
	    std::string("Interpreting the ")+uint2ordinal(mIndex+1)+std::string(" module")
	);
	Beagle_LogObjectDebugM(
	    ioContext.getSystem().getLogger(),
	    "EMA", "Beagle::GP::Module",
	    *ioTree
	);
	(*ioTree)[0].mPrimitive->execute(outResult, ioContext);
	ioContext.popCallStack();
	ioContext.checkExecutionTime();
	ioContext.setGenotypeHandle(lOldGenotypeHandle);
	ioContext.setGenotypeIndex(lOldGenotypeIndex);
	Beagle_StackTraceEndM("void GP::Module::invoke(GP::Datum& outResult, GP::Tree::Handle ioTree, GP::Context& ioContext)");
}
예제 #7
0
/*!
 *  \brief Validate the arguments position in the tree.
 *  \param ioContext Evolutionary context.
 *  \return True if the argument is correctly positioned, false if not.
 *  \throw Beagle::AssertException If the context is in a bad state.
 */
bool GP::Argument::validate(GP::Context& ioContext) const
{
	Beagle_StackTraceBeginM();
	if(GP::Primitive::validate(ioContext) == false) return false;
	if(ioContext.getGenotypeIndex() == 0) return false;
	if(mIndex >= ioContext.getGenotype().getNumberArguments()) return false;
	return true;
	Beagle_StackTraceEndM();
}
예제 #8
0
/*!
 *  \brief Return selection weight of the argument primitive.
 *  \param inNumberArguments Number of arguments to get weight for.
 *  \param ioContext Evolutionary context.
 *  \return Selection weight for the given number of arguments.
 */
double GP::Argument::getSelectionWeight(unsigned int inNumberArguments,
                                        GP::Context& ioContext) const
{
	Beagle_StackTraceBeginM();
	if(ioContext.getGenotypeIndex() == 0) return 0.0;
	if((inNumberArguments==0) || (inNumberArguments==GP::Primitive::eAny)) {
		const unsigned int lTreeNbArgs = ioContext.getGenotype().getNumberArguments();
		if(lTreeNbArgs > 0) return double(lTreeNbArgs);
	}
	return 0.0;
	Beagle_StackTraceEndM();
}
예제 #9
0
/*!
 *  \brief Interpret the GP individual.
 *  \param outResult Datum containing the result of the interpretation.
 *  \param ioContext GP evolutionary context.
 *  \throw Beagle::ObjectException When individual or tree are empty.
 *  \throw Beagle::AssertException When context is not correctly set.
 *  \throw Beagle::GP::MaxNodesExecutionException If number of nodes execution is more than allowed.
 *  \throw Beagle::GP::MaxTimeExecutionException If elapsed execution time is more than allowed.
 */
void GP::Individual::run(GP::Datum& outResult, GP::Context& ioContext)
{
	Beagle_StackTraceBeginM();
	if(&ioContext.getIndividual() != this) {
		std::ostringstream lOSS;
		lOSS << "In GP::Individual::run():  For the given context, ";
		lOSS << "getIndividual() did not return the same individual as was passed to this (run) ";
		lOSS << "method. Consider setting the context's individual to be the same by using the ";
		lOSS << "method Context::setIndividualHandle().";
		throw Beagle_RunTimeExceptionM(lOSS.str());
	}
	if(empty()) throw Beagle_ObjectExceptionM("Could not interpret, individual has no trees!");
	if((*this)[0]->empty()) throw Beagle_ObjectExceptionM("Could not interpret, 1st tree is empty!");
	Tree::Handle lOldTreeHandle = ioContext.getGenotypeHandle();
	unsigned int lOldTreeIndex  = ioContext.getGenotypeIndex();
	ioContext.setGenotypeIndex(0);
	ioContext.setGenotypeHandle((*this)[0]);
	Beagle_LogVerboseM(
	    ioContext.getSystem().getLogger(),
	    std::string("Running the ")+uint2ordinal(ioContext.getIndividualIndex()+1)+
	    std::string(" individual")
	);
	Beagle_LogDebugM(
	    ioContext.getSystem().getLogger(),
	    std::string("The individual is: ")
	);
	Beagle_LogDebugM(
	    ioContext.getSystem().getLogger(),
	    (*this)
	);
	Beagle_LogDebugM(
	    ioContext.getSystem().getLogger(),
	    std::string("Executing the first tree root node '")+
	    (*(*this)[0])[0].mPrimitive->getName()+"'"
	);
	ioContext.setNodesExecutionCount(0);
	ioContext.incrementNodesExecuted();
	ioContext.getExecutionTimer().reset();
	ioContext.pushCallStack(0);
	(*(*this)[0])[0].mPrimitive->execute(outResult, ioContext);
	ioContext.popCallStack();
	ioContext.checkExecutionTime();
	Beagle_LogDebugM(
	    ioContext.getSystem().getLogger(),
	    std::string("Result of executing the ")+uint2ordinal(ioContext.getIndividualIndex()+1)+
	    std::string(" individual: ")+outResult.serialize()
	);
	ioContext.setGenotypeIndex(lOldTreeIndex);
	ioContext.setGenotypeHandle(lOldTreeHandle);
	Beagle_StackTraceEndM();
}
예제 #10
0
/*!
 *  \brief Validate the ADF position in the tree.
 *  \param ioContext Evolutionary context.
 *  \return True if the ADF is correctly positioned, false if not.
 *  \throw Beagle::AssertException If the context is in a bad state.
 */
bool GP::ADF::validate(GP::Context& ioContext) const
{
	Beagle_StackTraceBeginM();
	if(mIndex <= ioContext.getGenotypeIndex()) {
		Beagle_LogDebugM(
		    ioContext.getSystem().getLogger(),
		    "validation","Beagle::GP::ADF::validate",
		    std::string("Validation failed because the ADF's index (")+uint2str(mIndex)+
		    ") is less than or equal to the genotype index ("+uint2str(ioContext.getGenotypeIndex())+")"
		);
		return false;
	}
	if(mIndex >= ioContext.getIndividual().size()) {
		Beagle_LogDebugM(
		    ioContext.getSystem().getLogger(),
		    "validation","Beagle::GP::ADF::validate",
		    std::string("Validation failed because the ADF's index (")+uint2str(mIndex)+
		    ") is greater than or equal to the individual's size ("+
		    uint2str(ioContext.getIndividual().size())+")"
		);
		return false;
	}
	if(ioContext.getIndividual()[mIndex]->getNumberArguments() != getNumberArguments()) {
		Beagle_LogDebugM(
		    ioContext.getSystem().getLogger(),
		    "validation","Beagle::GP::ADF::validate",
		    std::string("Validation failed because the number of arguments for the tree (")+
		    uint2str(ioContext.getIndividual()[mIndex]->getNumberArguments())+
		    ") differed from the number of arguments for the primitive ("+
		    uint2str(getNumberArguments())+")"
		);
		return false;
	}
	return GP::Primitive::validate(ioContext);
	Beagle_StackTraceEndM("bool GP::ADF::validate(GP::Context& ioContext) const");
}
예제 #11
0
/*!
 *  \brief Return indices of the trees that can be invoked by the ADF.
 *  \param outCandidates Indices of tree that can be selected as invokable in the actual context.
 *  \param inNumberArguments Number of arguments for which the selection is desired.
 *  \param ioContext Evolutionary context.
 */
void GP::ADF::getCandidatesToInvoke(std::vector<unsigned int>& outCandidates,
                                    unsigned int inNumberArguments,
                                    GP::Context& ioContext) const
{
	Beagle_StackTraceBeginM();
	outCandidates.clear();
	for(unsigned int i=(ioContext.getGenotypeIndex()+1); i<ioContext.getIndividual().size(); ++i) {
		GP::Tree::Handle lTree = castHandleT<GP::Tree>(ioContext.getIndividual()[i]);
		const unsigned int lNbArgsTree = lTree->getNumberArguments();
		if(inNumberArguments == GP::Primitive::eAny) outCandidates.push_back(i);
		else if((inNumberArguments == GP::Primitive::eBranch) && (lNbArgsTree>0))
			outCandidates.push_back(i);
		else if(inNumberArguments == lNbArgsTree) outCandidates.push_back(i);
	}
	Beagle_StackTraceEndM("void GP::ADF::getCandidatesToInvoke(std::vector<unsigned int>& outCandidates, unsigned int inNumberArguments, GP::Context& ioContext) const");
}
예제 #12
0
/*!
 *  \brief Invoke GP tree to execute as ADF.
 *  \param outResult Result of GP tree invocation
 *  \param ioTree Tree to invoke.
 *  \param ioContext Evolutionary context.
 */
void GP::ADF::invoke(GP::Datum& outResult, GP::Tree::Handle ioTree, GP::Context& ioContext)
{
	Beagle_StackTraceBeginM();
	GP::Tree::Handle lOldGenotypeHandle = ioContext.getGenotypeHandle();
	unsigned int lOldGenotypeIndex = ioContext.getGenotypeIndex();
	ioContext.setGenotypeHandle(ioTree);
	ioContext.setGenotypeIndex(mIndex);
	ioContext.incrementNodesExecuted();
	ioContext.pushCallStack(0);
	(*ioTree)[0].mPrimitive->execute(outResult, ioContext);
	ioContext.popCallStack();
	ioContext.checkExecutionTime();
	ioContext.setGenotypeHandle(lOldGenotypeHandle);
	ioContext.setGenotypeIndex(lOldGenotypeIndex);
	Beagle_StackTraceEndM("void GP::ADF::invoke(GP::Datum& outResult, GP::Tree::Handle ioTree, GP::Context& ioContext)");
}
예제 #13
0
/*!
 *  \brief Build a roulette of nodes that can be selected following the constraints penalties.
 *  \param ioRoulette Roulette of nodes that can be selected following the constraints given.
 *  \param inSelectABranch True if node to select must be a branch, false if it must a leaf.
 *  \param inNodeReturnType Desired return type for the nodes to be selected.
 *  \param inMaxSubTreeDepth Maximum sub tree depth allowed of the node to be selected.
 *  \param inMaxSubTreeSize Maximum sub tree size allowed of the node to be selected.
 *  \param inActualIndex Index in actual tree of the node processed.
 *  \param inTree Tree processed.
 *  \param ioContext Evolutionary context.
 *  \return Max depth of subtree processed.
 */
unsigned int STGP::CrossoverConstrainedOp::buildRouletteWithType(
    RouletteT< std::pair<unsigned int,unsigned int> >& ioRoulette,
    bool inSelectABranch,
    const std::type_info* inNodeReturnType,
    unsigned int inMaxSubTreeDepth,
    unsigned int inMaxSubTreeSize,
    unsigned int inActualIndex,
    GP::Tree& inTree,
    GP::Context& ioContext) const
{
	Beagle_StackTraceBeginM();
	const unsigned int lNbArgs = inTree[inActualIndex].mPrimitive->getNumberArguments();
	const unsigned int lSubTreeSize = inTree[inActualIndex].mSubTreeSize;
	const bool lGoodArity = ((inTree.size()==1) || ((lNbArgs==0) != inSelectABranch));
	ioContext.pushCallStack(inActualIndex);
	const std::type_info* lNodeType = inTree[inActualIndex].mPrimitive->getReturnType(ioContext);
	const bool lCompatibleTyping = ((inNodeReturnType==NULL) || (lNodeType==NULL) ||
	                                (inNodeReturnType==lNodeType));
	unsigned int lChildIndex = inActualIndex+1;
	unsigned int lMaxDepthDown = 0;
	for(unsigned int i=0; i<lNbArgs; ++i) {
		unsigned int lChildDepth = buildRouletteWithType(ioRoulette,
		                           inSelectABranch,
		                           inNodeReturnType,
		                           inMaxSubTreeDepth,
		                           inMaxSubTreeSize,
		                           lChildIndex,
		                           inTree,
		                           ioContext);
		lChildIndex += inTree[lChildIndex].mSubTreeSize;
		if(lChildDepth > lMaxDepthDown) lMaxDepthDown = lChildDepth;
	}
	++lMaxDepthDown;
	const unsigned int lMaxDepthUp = ioContext.getCallStackSize();
	ioContext.popCallStack();
	if(lGoodArity && lCompatibleTyping && (lSubTreeSize<=inMaxSubTreeSize) &&
	        (lMaxDepthDown<=inMaxSubTreeDepth) && (lMaxDepthUp<=inMaxSubTreeDepth)) {
		std::pair<unsigned int,unsigned int> lPair(ioContext.getGenotypeIndex(), inActualIndex);
		ioRoulette.insert(lPair, 1.0);
	}
	return lMaxDepthDown;
	Beagle_StackTraceEndM();
}
예제 #14
0
/*!
 *  \brief Select a node for mating in the given individual, following the constraints penalties.
 *  \param outSelectTreeIndex Tree index of the selected node.
 *  \param outSelectNodeIndex Index of the selected node.
 *  \param inSelectABranch True if node to select must be a branch, false if it must a leaf.
 *  \param inNodeReturnType Desired return type for the nodes to be selected.
 *  \param inPrimitSetIndex Primitive set index to which the tree must be associated.
 *  \param inMaxSubTreeDepth Maximum sub tree depth allowed of the node to be selected.
 *  \param inMaxSubTreeSize Maximum sub tree size allowed of the node to be selected.
 *  \param inIndividual Individual to select the node from.
 *  \param ioContext Evolutionary context.
 *  \return True if there was node to select, false if no node respected all constraints.
 */
bool STGP::CrossoverConstrainedOp::selectNodeToMateWithType(unsigned int& outSelectTreeIndex,
        unsigned int& outSelectNodeIndex,
        bool inSelectABranch,
        const std::type_info* inNodeReturnType,
        unsigned int inPrimitSetIndex,
        unsigned int inMaxSubTreeDepth,
        unsigned int inMaxSubTreeSize,
        GP::Individual& inIndividual,
        GP::Context& ioContext) const
{
	Beagle_StackTraceBeginM();
	RouletteT< std::pair<unsigned int,unsigned int> > lRoulette;
	GP::Tree::Handle lOldTreeHandle = ioContext.getGenotypeHandle();
	const unsigned int lOldTreeIndex = ioContext.getGenotypeIndex();
	ioContext.emptyCallStack();
	for(unsigned int i=0; i<inIndividual.size(); ++i) {
		if(inIndividual[i]->getPrimitiveSetIndex() != inPrimitSetIndex) continue;
		ioContext.setGenotypeHandle(inIndividual[i]);
		ioContext.setGenotypeIndex(i);
		buildRouletteWithType(lRoulette,
		                      inSelectABranch,
		                      inNodeReturnType,
		                      inMaxSubTreeDepth,
		                      inMaxSubTreeSize,
		                      0,
		                      *inIndividual[i],
		                      ioContext);
	}
	ioContext.setGenotypeIndex(lOldTreeIndex);
	ioContext.setGenotypeHandle(lOldTreeHandle);
	if(lRoulette.size() == 0) return false;
	std::pair<unsigned int,unsigned int> lSelectedNode =
	    lRoulette.select(ioContext.getSystem().getRandomizer());
	outSelectTreeIndex = lSelectedNode.first;
	outSelectNodeIndex = lSelectedNode.second;
	return true;
	Beagle_StackTraceEndM();
}
/*!
 *  \brief Initialize a GP constrained sub-tree of a specified depth using the "full" approach.
 *  \param ioTree Tree containing the sub-tree to initialize.
 *  \param inSubTreeDepth Depth of the sub-tree to initialize.
 *  \param ioContext Evolutionary context.
 *  \return Generated sub-tree size.
 */
unsigned int GP::InitFullConstrainedOp::initConstrainedSubTreeFull(GP::Tree& ioTree,
        unsigned int inSubTreeDepth,
        GP::Context& ioContext) const
{
	Beagle_StackTraceBeginM();
	Beagle_AssertM(inSubTreeDepth>0);

	GP::PrimitiveSet& lPrimitSet = ioTree.getPrimitiveSet(ioContext);
	GP::Primitive::Handle lPrimit = NULL;
	const unsigned int lNodeIndex = ioTree.size();
	for(unsigned int lAttempt=0; lAttempt < mNumberAttempts->getWrappedValue(); ++lAttempt) {
#ifdef BEAGLE_HAVE_RTTI
		const std::type_info* lDesiredType = NULL;
		if(ioTree.size()==0) lDesiredType = ioTree.getRootType(ioContext);
		else {
			const unsigned int lParentIndex = ioContext.getCallStackTop();
			unsigned int lArgsIndexChild = 0;
			for(unsigned int lChildIndex=(lParentIndex+1);
			        lChildIndex!=lNodeIndex; lChildIndex += ioTree[lChildIndex].mSubTreeSize) {
				Beagle_AssertM(lChildIndex <= ioTree.size());
				++lArgsIndexChild;
				Beagle_AssertM(lArgsIndexChild < ioTree[lParentIndex].mPrimitive->getNumberArguments());
			}
			lDesiredType = ioTree[lParentIndex].mPrimitive->getArgType(lArgsIndexChild, ioContext);
		}
		if(inSubTreeDepth == 1) {
			lPrimit = lPrimitSet.selectWithType(GP::Primitive::eTerminal, lDesiredType, ioContext);
			if(!lPrimit) return 0;
			lPrimit = lPrimit->giveReference(GP::Primitive::eTerminal, ioContext);
		} else {
			lPrimit = lPrimitSet.selectWithType(GP::Primitive::eBranch, lDesiredType, ioContext);
			if(!lPrimit) return 0;
			lPrimit = lPrimit->giveReference(GP::Primitive::eBranch, ioContext);
		}
#else // BEAGLE_HAVE_RTTI
		if(inSubTreeDepth == 1) {
			lPrimit = lPrimitSet.select(GP::Primitive::eTerminal, ioContext);
			if(!lPrimit) {
				string lMessage = "There is no leaf (primitive without argument) in the ";
				lMessage += uint2ordinal(ioContext.getGenotypeIndex());
				lMessage += " primitive set!";
				throw Beagle_RunTimeExceptionM(lMessage);
			}
			lPrimit = lPrimit->giveReference(GP::Primitive::eTerminal, ioContext);
		} else {
			lPrimit = lPrimitSet.select(GP::Primitive::eBranch, ioContext);
			if(!lPrimit) {
				string lMessage = "There is no branch (primitive with arguments) in the ";
				lMessage += uint2ordinal(ioContext.getGenotypeIndex());
				lMessage += " primitive set!";
				throw Beagle_RunTimeExceptionM(lMessage);
			}
			lPrimit = lPrimit->giveReference(GP::Primitive::eBranch, ioContext);
		}
#endif // BEAGLE_HAVE_RTTI
		ioTree.push_back(GP::Node(lPrimit, 0));
		ioContext.pushCallStack(lNodeIndex);
		if(lPrimit->validate(ioContext)) {
			unsigned int lSubTreeSize = 1;
			bool lGoodInit = true;
			for(unsigned int i=0; i<lPrimit->getNumberArguments(); i++) {
				unsigned int lArgSubTreeSize =
				    initConstrainedSubTreeFull(ioTree, inSubTreeDepth-1, ioContext);
				if(lArgSubTreeSize == 0) {
					for(unsigned int j=1; j<lSubTreeSize; j++) ioTree.pop_back();
					lGoodInit = false;
					break;
				}
				lSubTreeSize += lArgSubTreeSize;
			}
			if(lGoodInit) {
				ioContext.popCallStack();
				ioTree[lNodeIndex].mSubTreeSize = lSubTreeSize;
				return lSubTreeSize;
			}
		} else {
			Beagle_LogDebugM(
			    ioContext.getSystem().getLogger(),
			    "initialization", "Beagle::GP::InitFullConstrainedOp",
			    "Primitive failed validation testing"
			);
		}
		ioContext.popCallStack();
		ioTree.pop_back();
	}
	Beagle_LogDebugM(
	    ioContext.getSystem().getLogger(),
	    "initialization", "Beagle::GP::InitFullConstrainedOp",
	    "Could not correctly initialize this node; backtracking instead."
	);
	return 0; // Could not initialize this node correctly, backtracking instead.
	Beagle_StackTraceEndM("unsigned int GP::InitFullConstrainedOp::initConstrainedSubTreeFull(GP::Tree& ioTree, unsigned int inSubTreeDepth, GP::Context& ioContext) const");
}