コード例 #1
0
ファイル: Individual.cpp プロジェクト: GhostGambler/beagle
/*!
 *  \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();
}
コード例 #2
0
/*!
 *  \brief Generate a new ADF primitive from the given specifications.
 *  \param inIndex Tree index for which the primitive is created.
 *  \param inName Name of the primitive generated.
 *  \param inArgsName Name of the arguments associated to the invoker created.
 *  \param ioContext Evolutionary context.
 */
GP::Invoker::Handle GP::ADF::generateInvoker(unsigned int inIndex,
        std::string inName,
        std::string inArgsName,
        GP::Context& ioContext) const
{
	Beagle_StackTraceBeginM();
	if(inIndex == UINT_MAX) {
		Beagle_LogDebugM(
		    ioContext.getSystem().getLogger(),
		    "primitive selection","Beagle::GP::ADF::generateInvoker",
		    "Generated ADF with UINT_MAX"
		);

		return new GP::ADF(UINT_MAX, UINT_MAX, inName, inArgsName);
	} else {
		GP::Tree::Handle lTree = ioContext.getIndividual()[inIndex];

		Beagle_LogDebugM(
		    ioContext.getSystem().getLogger(),
		    "primitive selection","Beagle::GP::ADF::generateInvoker",
		    std::string("Generated ADF with index ")+uint2str(inIndex)+" ("+uint2str(lTree->getNumberArguments())+" args)"
		);

		return new GP::ADF(inIndex, lTree->getNumberArguments(), inName, inArgsName);
	}
	Beagle_StackTraceEndM("GP::Invoker::Handle GP::ADF::generateInvoker(unsigned int inIndex, string inName, string inArgsName, GP::Context& ioContext) const");
}
コード例 #3
0
/*!
 *  \brief Execute the call to the associated tree with the given parameters.
 *  \param outResult Result of the invocation.
 *  \param ioContext Evolutionary context.
 */
void GP::Invoker::execute(GP::Datum& outResult, GP::Context& ioContext)
{
	Beagle_StackTraceBeginM();
	GP::Tree::Handle lTree = getInvokedTree(ioContext);
	Beagle_AssertM(lTree->getNumberArguments() == getNumberArguments());
	if(getNumberArguments() == 0) {
		invoke(outResult, lTree, ioContext);
	} else {
		GP::Argument::Handle lArg =
		    castHandleT<GP::Argument>(lTree->getPrimitiveSet(ioContext).getPrimitiveByName(mArgsName));
		if(lArg==NULL) {
			std::string lMessage = "The argument named '";
			lMessage += mArgsName;
			lMessage += " associated to the invoker named '";
			lMessage += getName();
			lMessage += "' does not refer to a valid primitive in the set";
			lMessage += " of the tree associated to the invoker.";
			throw Beagle_RunTimeExceptionM(lMessage);
		}
		lArg->pushExecutionContext(getNumberArguments(), ioContext);
		invoke(outResult, lTree, ioContext);
		lArg->popExecutionContext();
	}
	Beagle_StackTraceEndM("void GP::Invoker::execute(GP::Datum& outResult, GP::Context& ioContext)");
}
コード例 #4
0
/*!
 *  \brief  Return the string tagging the type of data returned by the primitive.
 *  \param  ioContext Evolutionary context.
 *  \return String tagging the type of data returned.
 *  \throw  InternalException If RTTI is disabled and the method is not properly overdefined.
 */
const std::type_info* GP::Invoker::getReturnType(GP::Context& ioContext) const
{
	Beagle_StackTraceBeginM();
	if(mIndex == eGenerator) return NULL;
	GP::Tree::Handle lTree = getInvokedTree(ioContext);
	GP::Tree::Handle lOldTreeHandle = ioContext.getGenotypeHandle();
	const unsigned int lOldTreeIndex = ioContext.getGenotypeIndex();
	ioContext.setGenotypeHandle(lTree);
	ioContext.setGenotypeIndex(mIndex);
	const std::type_info* lReturnType = lTree->getRootType(ioContext);
	ioContext.setGenotypeIndex(lOldTreeIndex);
	ioContext.setGenotypeHandle(lOldTreeHandle);
	return lReturnType;
	Beagle_StackTraceEndM("const std::type_info* GP::Invoker::getArgType(unsigned int inN, GP::Context& ioContext) const");
}
コード例 #5
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");
}
コード例 #6
0
ファイル: Module.cpp プロジェクト: GhostGambler/beagle
/*!
 *  \brief Generate a new Module primitive from the given specifications.
 *  \param inIndex Tree index for which the primitive is created.
 *  \param inName Name of the primitive generated.
 *  \param inArgsName Name of the arguments associated to the invoker created.
 *  \param ioContext Evolutionary context.
 */
GP::Invoker::Handle GP::Module::generateInvoker(unsigned int inIndex,
        std::string inName,
        std::string inArgsName,
        GP::Context& ioContext) const
{
	Beagle_StackTraceBeginM();
	Component::Handle lComponent = ioContext.getSystem().getComponent("ModuleVector");
	GP::ModuleVectorComponent::Handle lModVector =
	    castHandleT<GP::ModuleVectorComponent>(lComponent);
	if(lModVector==NULL) {
		throw Beagle_RunTimeExceptionM(std::string("GP system is not configured with a module vector. ")+
		                               std::string("Consider adding a GP::ModuleVectorComponent object to the system."));
	}
	GP::Tree::Handle lTree = (*lModVector)[inIndex];
	Beagle_AssertM(lTree != NULL);
	return new GP::Module(inIndex, lTree->getNumberArguments(), inName, inArgsName);
	Beagle_StackTraceEndM();
}
コード例 #7
0
/*!
 *  \brief Return the tag of the type of data needed as input for the primitive.
 *  \param inN Index of the argument to get the type tag.
 *  \param ioContext Evolutionary context.
 *  \return String tagging the data type needed.
 *  \throw AssertException If the index inN given is > to 1.
 *  \throw InternalException If RTTI is disabled and the method is not properly overdefined.
 */
const std::type_info* GP::Invoker::getArgType(unsigned int inN, GP::Context& ioContext) const
{
	Beagle_StackTraceBeginM();
	Beagle_AssertM(inN < getNumberArguments());
	if(mIndex == eGenerator) {
		std::ostringstream lOSS;
		lOSS << "Could not get the arguments typing of the '" << getName() << "' invoker primitive. ";
		lOSS << "The primitive is actually in a generator state, so the index of the tree ";
		lOSS << "refered by the primitive is not specified. It is likely that there is a problem ";
		lOSS << "in the setting of your system, as the argument typing is called only when the ";
		lOSS << "primitive is completely instantiated, that is used as the part of a GP tree, ";
		lOSS << "with an index value refering to another GP tree to invoke.";
		throw Beagle_RunTimeExceptionM(lOSS.str());
	}
	GP::Tree::Handle lTree = getInvokedTree(ioContext);
	GP::Tree::Handle lOldTreeHandle = ioContext.getGenotypeHandle();
	ioContext.setGenotypeHandle(lTree);
	GP::Argument::Handle lArg =
	    castHandleT<GP::Argument>(lTree->getPrimitiveSet(ioContext).getPrimitiveByName(mArgsName));
	const std::type_info* lArgType = lArg->getReturnType(ioContext);
	ioContext.setGenotypeHandle(lOldTreeHandle);
	return lArgType;
	Beagle_StackTraceEndM("const std::type_info* GP::Invoker::getArgType(unsigned int inN, GP::Context& ioContext) const");
}
コード例 #8
0
/*!
 *  \brief Expand given module of a GP tree.
 *  \param inNodeToExpand Index of node to expand in GP tree.
 *  \param ioTree Tree from which module will be expanded.
 *  \param ioContext Evolutionary context.
 */
void GP::ModuleExpandOp::expand(unsigned int inNodeToExpand,
                                GP::Tree& ioTree,
                                GP::Context& ioContext)
{
	Beagle_StackTraceBeginM();
	// Log tree before expansion.
	Beagle_LogDebugM(
	    ioContext.getSystem().getLogger(),
	    "Tree before expansion"
	);
	Beagle_LogDebugM(
	    ioContext.getSystem().getLogger(),
	    ioTree
	);

	// Get the module index and reference.
	Module::Handle lModuleInstance = castHandleT<Module>(ioTree[inNodeToExpand].mPrimitive);
	unsigned int lModuleIndex = lModuleInstance->getIndex();
	Beagle_LogVerboseM(
	    ioContext.getSystem().getLogger(),
	    std::string("Expanding ")+uint2ordinal(lModuleIndex+1)+
	    std::string(" module (called from ")+uint2ordinal(inNodeToExpand+1)+
	    std::string(" node of the tree)")
	);
	ModuleVectorComponent::Handle lModuleVectorComponent =
	    castHandleT<ModuleVectorComponent>(ioContext.getSystem().getComponent("ModuleVector"));
	if(lModuleVectorComponent==NULL) {
		throw Beagle_RunTimeExceptionM(std::string("GP system is not configured with a module vector. ")+
		                               std::string("Consider adding a GP::ModuleVectorComponent object to the system."));
	}
	Beagle::GP::Tree::Handle lModule = (*lModuleVectorComponent)[lModuleIndex];
	Beagle_LogDebugM(
	    ioContext.getSystem().getLogger(),
	    *lModule
	);

	// Generate new tree.
	const Factory& lFactory = ioContext.getSystem().getFactory();
	GP::Tree::Alloc::Handle lTreeAlloc =
		castHandleT<GP::Tree::Alloc>(lFactory.getConceptAllocator("Genotype"));
	GP::Tree::Handle lNewTree = castHandleT<GP::Tree>(lTreeAlloc->allocate());
	std::string lArgName = lModuleInstance->getArgsName();
	ioTree.setContextToNode(inNodeToExpand, ioContext);
	for(unsigned int i=0; i<lModule->size(); ++i) {
		if((*lModule)[i].mPrimitive->getName() != lArgName) {
			lNewTree->push_back(GP::Node((*lModule)[i].mPrimitive));
		} else {
			GP::Argument::Handle lArg = castHandleT<GP::Argument>((*lModule)[i].mPrimitive);
			const unsigned int lChildIndex =
			    ioTree[inNodeToExpand].mPrimitive->getChildrenNodeIndex(lArg->getIndex(), ioContext);
			lNewTree->insert(lNewTree->end(), ioTree.begin()+lChildIndex,
			                 ioTree.begin()+lChildIndex+ioTree[lChildIndex].mSubTreeSize);
		}
	}
	ioTree.erase(ioTree.begin()+inNodeToExpand,
	             ioTree.begin()+inNodeToExpand+ioTree[inNodeToExpand].mSubTreeSize);
	ioTree.insert(ioTree.begin()+inNodeToExpand, lNewTree->begin(), lNewTree->end());
	ioTree.fixSubTreeSize();

	// Log results.
	Beagle_LogDebugM(
	    ioContext.getSystem().getLogger(),
	    "Tree after expansion"
	);
	Beagle_LogDebugM(
	    ioContext.getSystem().getLogger(),
	    ioTree
	);
	
	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 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)");
}
コード例 #10
0
/*!
 *  \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();
}
コード例 #11
0
/*!
 *  \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)");
}