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