/*! * \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(); } }
/*! * \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(); }
/*! * \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(); }