/*! * \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 Swap mutate a constrained GP individual. * \param ioIndividual GP individual to swap mutate. * \param ioContext Context of the evolution. * \return True if the individual is effectively mutated, false if not. */ bool STGP::MutationSwapConstrainedOp::mutate(Beagle::Individual& ioIndividual, Beagle::Context& ioContext) { Beagle_StackTraceBeginM(); GP::Individual& lIndividual = castObjectT<GP::Individual&>(ioIndividual); GP::Context& lContext = castObjectT<GP::Context&>(ioContext); double lDistrProba = mDistributionProba->getWrappedValue(); unsigned int lNumberAttempts = mNumberAttempts->getWrappedValue(); bool lMutationDone = false; 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(); } GP::Tree& lTree = *lIndividual[lChoosenTree]; if(lTree.size() == 0) return false; GP::Tree::Handle lOldTreeHandle = lContext.getGenotypeHandle(); unsigned int lOldTreeIndex = lContext.getGenotypeIndex(); lContext.setGenotypeHandle(lIndividual[lChoosenTree]); lContext.setGenotypeIndex(lChoosenTree); Beagle_LogDebugM( ioContext.getSystem().getLogger(), "Individual before constrained GP tree swap mutation" ); Beagle_LogDebugM( ioContext.getSystem().getLogger(), ioIndividual ); if(lTree.size() > 1) { bool lTypeNode = (lContext.getSystem().getRandomizer().rollUniform(0., 1.) < lDistrProba); while((lTree[lChoosenNode].mPrimitive->getNumberArguments() != 0) != lTypeNode) { lChoosenNode = lContext.getSystem().getRandomizer().rollInteger(0, lTree.size()-1); } } GP::Primitive::Handle lOriginalPrimitive = lTree[lChoosenNode].mPrimitive; Beagle_LogVerboseM( ioContext.getSystem().getLogger(), std::string("Trying to constrained GP tree swap mutate the ")+uint2ordinal(lChoosenNode+1)+ std::string(" node (primitive: '")+lOriginalPrimitive->getName()+ std::string("' nb args: ")+uint2str(lOriginalPrimitive->getNumberArguments())+ std::string(") of the ")+uint2ordinal(lChoosenTree+1)+std::string(" tree") ); GP::PrimitiveSet& lPrimitiveSet = lTree.getPrimitiveSet(lContext); unsigned int lNbArgsPrimit = lTree[lChoosenNode].mPrimitive->getNumberArguments(); lTree.setContextToNode(lChoosenNode, lContext); for(unsigned int lAttempt=0; lAttempt < lNumberAttempts; ++lAttempt) { GP::Primitive::Handle lChoosenPrimitive = lPrimitiveSet.select(lNbArgsPrimit, lContext); if(lChoosenPrimitive==NULL) break; lTree[lChoosenNode].mPrimitive = lChoosenPrimitive->giveReference(lNbArgsPrimit, lContext); Beagle_LogVerboseM( ioContext.getSystem().getLogger(), std::string("Trying the primitive '")+lChoosenPrimitive->getName()+ std::string("'") ); if(lTree.validateSubTree(lChoosenNode, lContext)) { lMutationDone = true; Beagle_LogVerboseM( ioContext.getSystem().getLogger(), "Constrained GP tree swap mutation valid" ); break; } else { lTree[lChoosenNode].mPrimitive = lOriginalPrimitive; Beagle_LogVerboseM( ioContext.getSystem().getLogger(), "Constrained GP tree swap mutation invalid" ); } } lContext.setGenotypeHandle(lOldTreeHandle); lContext.setGenotypeIndex(lOldTreeIndex); if(lMutationDone) { Beagle_LogDebugM( ioContext.getSystem().getLogger(), "Individual after constrained GP swap mutation" ); Beagle_LogDebugM( ioContext.getSystem().getLogger(), ioIndividual ); } else { Beagle_LogVerboseM( ioContext.getSystem().getLogger(), "Unable to swap mutate the constrained individual" ); } return lMutationDone; 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"); }