/*!
 *  \brief  Exchange two GP trees on given points.
 *  \param  ioTree1 First tree to mate.
 *  \param  inNode1 Node index of the swap subtree first point.
 *  \param  ioContext1 Evolutionary context relatively to the first tree.
 *  \param  ioTree2 Second tree to mate.
 *  \param  inNode2 Node index of the swap subtree second point.
 *  \param  ioContext2 Evolutionary context relatively to the second tree.
 */
void GP::MutationSwapSubtreeOp::exchangeSubTrees(GP::Tree& ioTree1,
        unsigned int inNode1,
        GP::Context& ioContext1,
        GP::Tree& ioTree2,
        unsigned int inNode2,
        GP::Context& ioContext2)
{
	Beagle_StackTraceBeginM();
	Beagle_AssertM(&ioTree1 != &ioTree2);
	unsigned int lSwapSize1 = ioTree1[inNode1].mSubTreeSize;
	unsigned int lSwapSize2 = ioTree2[inNode2].mSubTreeSize;
	if(lSwapSize1 <= lSwapSize2) {
		std::swap_ranges(ioTree1.begin()+inNode1, ioTree1.begin()+inNode1+lSwapSize1, ioTree2.begin()+inNode2);
		ioTree1.insert(ioTree1.begin()+inNode1+lSwapSize1,
		               ioTree2.begin()+inNode2+lSwapSize1,
		               ioTree2.begin()+inNode2+lSwapSize2);
		ioTree2.erase(ioTree2.begin()+inNode2+lSwapSize1, ioTree2.begin()+inNode2+lSwapSize2);
	} else {
		std::swap_ranges(ioTree1.begin()+inNode1, ioTree1.begin()+inNode1+lSwapSize2, ioTree2.begin()+inNode2);
		ioTree2.insert(ioTree2.begin()+inNode2+lSwapSize2,
		               ioTree1.begin()+inNode1+lSwapSize2,
		               ioTree1.begin()+inNode1+lSwapSize1);
		ioTree1.erase(ioTree1.begin()+inNode1+lSwapSize2, ioTree1.begin()+inNode1+lSwapSize1);
	}
	int lDiffSize = lSwapSize1 - lSwapSize2;
	for(unsigned int i=0; i<(ioContext1.getCallStackSize()-1); i++)
		ioTree1[ioContext1.getCallStackElement(i)].mSubTreeSize -= lDiffSize;
	for(unsigned int j=0; j<(ioContext2.getCallStackSize()-1); j++)
		ioTree2[ioContext2.getCallStackElement(j)].mSubTreeSize += lDiffSize;
	Beagle_StackTraceEndM();
}
void TreeSTag::removeNOPLoop(unsigned int inN, GP::Context& ioContext) {
	GP::Tree& lActualTree = ioContext.getGenotype();
	
	if(lActualTree[inN].mPrimitive->getName() == "NOP") {
		//Decrease the subtree size of the call stack
		for(unsigned i = 0; i < ioContext.getCallStackSize(); ++i) {
			lActualTree[ioContext.getCallStack()[i]].mSubTreeSize -= 1;
		}
		
		//Delete the primitive from the tree
		std::vector< GP::Node,BEAGLE_STLALLOCATOR<GP::Node> >::iterator lPrimitiveIter = lActualTree.begin();
		lPrimitiveIter += inN;
		lActualTree.erase(lPrimitiveIter);

		
//		cout << "Callstack: " << ioContext.getCallStack()[0];
//		for(unsigned int i = 1; i < ioContext.getCallStackSize() ; ++i) {
//			cout << ", " << ioContext.getCallStack()[0];
//		} cout << endl;
//		for(unsigned int i = 0; i < lActualTree.size(); ++i) {
//			cout << i << " : " << lActualTree[i].mPrimitive->getName() << " : " << lActualTree[i].mSubTreeSize << endl;
//		}
		
		removeNOPLoop(inN, ioContext);
		
	} else {
		//Parse all arguments
		ioContext.pushCallStack(inN);
		for(unsigned int i = 0; i < lActualTree[inN].mPrimitive->getNumberArguments(); ++i) {
			removeNOPLoop(lActualTree[inN].mPrimitive->getChildrenNodeIndex(i,ioContext), ioContext);
		}
		ioContext.popCallStack();
	}
}
Exemple #3
0
/*!
 *  \brief Return indices of the trees that can be invoked by the module.
 *  \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::Module::getCandidatesToInvoke(std::vector<unsigned int>& outCandidates,
                                       unsigned int inNumberArguments,
                                       GP::Context& ioContext) const
{
	Beagle_StackTraceBeginM();
	outCandidates.clear();
	for(unsigned int i=0; i<ioContext.getCallStackSize(); ++i) {
		if(ioContext.getGenotype()[ioContext.getCallStackElement(i)].mPrimitive->getName() == getName())
			return;
	}
	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."));
	}
	for(unsigned int i=0; i<lModVector->size(); ++i) {
		if((*lModVector)[i]==NULL) continue;
		const unsigned int lNbArgsTree = (*lModVector)[i]->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();
}
Exemple #4
0
/*!
 *  \brief Validate the module position in the tree.
 *  \param ioContext Evolutionary context.
 *  \return True if the module is correctly positioned, false if not.
 *  \throw Beagle::AssertException If the context is in a bad state.
 */
bool GP::Module::validate(GP::Context& ioContext) const
{
	Beagle_StackTraceBeginM();
	for(unsigned int i=0; i<ioContext.getCallStackSize(); ++i) {
		if(ioContext.getGenotype()[ioContext.getCallStackElement(i)].mPrimitive->getName() == getName())
			return false;
	}
	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."));
	}
	Beagle_AssertM((*lModVector)[mIndex]!=NULL);
	if((*lModVector)[mIndex]->getNumberArguments() != getNumberArguments()) return false;
	return GP::Primitive::validate(ioContext);
	Beagle_StackTraceEndM();
}
/*!
 *  \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();
}