/*! * \brief Set the value of the named GP primitive of the primitive sets. * \param inName Name of the variable to set. * \param inValue Value of the primitive. * \param ioContext Context of the evaluation. * \throw Beagle::RunTimeException If the named primitive is not found in any sets. */ void Coev::GPEvaluationOp::setValue(std::string inName, const Object& inValue, GP::Context& ioContext) const { Beagle_StackTraceBeginM(); GP::PrimitiveSuperSet::Handle lSuperSet = castHandleT<GP::PrimitiveSuperSet>(ioContext.getSystem().getComponent("GP-PrimitiveSuperSet")); if(lSuperSet == NULL) { throw Beagle_RunTimeExceptionM("There should be a GP::PrimitiveSuperSet component in the system"); } bool lValueFound = false; Beagle_LogDebugM( ioContext.getSystem().getLogger(), std::string("Setting the primitives named '")+inName+ std::string("' to the value: ")+inValue.serialize() ); for(unsigned int i=0; i<lSuperSet->size(); i++) { GP::Primitive::Handle lPrimitive = (*lSuperSet)[i]->getPrimitiveByName(inName); if(!lPrimitive) continue; lValueFound = true; lPrimitive->setValue(inValue); } if(lValueFound == false) { std::string lMessage = "The primitive named '"; lMessage += inName; lMessage += "' was not found in any "; lMessage += "of the primitive sets. Maybe the primitive was not properly inserted "; lMessage += "or the name is mispelled."; throw Beagle_RunTimeExceptionM(lMessage); } Beagle_StackTraceEndM(); }
/*! * \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(); }
bool Beagle::GP::MutationEphemeralOpT<T>::mutate(Beagle::Individual& ioIndividual, Beagle::Context& ioContext) { Beagle_StackTraceBeginM(); Beagle_LogDetailedM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationEphemeralOpT", std::string("Mutating ")+uint2ordinal(ioContext.getGenotypeIndex()+1)+ std::string(" individual with GP::MutationEphemeralOpT") ); GP::Individual& lIndividual = castObjectT<GP::Individual&>(ioIndividual); GP::Context& lContext = castObjectT<GP::Context&>(ioContext); // Get index of potential primitives with parameters that can be selected for mutation. std::vector< std::pair<unsigned int,unsigned int> > lPotentialParam; for(unsigned int i=0; i<lIndividual.size(); ++i) { GP::Tree& lTree = *lIndividual[i]; for(unsigned int j=0; j<lTree.size(); ++j) { if(lTree[j].mPrimitive->getName() == *mEphemeralName) { lPotentialParam.push_back(std::make_pair(i,j)); } } } // Return if there is not potential parameters. if(lPotentialParam.empty()) return false; // Mutating a primitive Beagle_LogDebugM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationEphemeralOpT", "Individual before GP parameters mutation" ); Beagle_LogObjectDebugM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationEphemeralOpT", ioIndividual ); // Store original context values unsigned int lOldGenotypeIndex = lContext.getGenotypeIndex(); GP::Tree::Handle lOldGenotypeHandle = lContext.getGenotypeHandle(); // Get reference to primitive to mutate and other objects. const unsigned int lSelectedParam = lContext.getSystem().getRandomizer().rollInteger(0,lPotentialParam.size()-1); GP::Tree::Handle lSelectedTree = lIndividual[lPotentialParam[lSelectedParam].first]; lContext.setGenotypeIndex(lPotentialParam[lSelectedParam].first); lContext.setGenotypeHandle(lSelectedTree); Beagle_LogVerboseM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationEphemeralOpT", std::string("Mutating the parameter of the ")+ uint2ordinal(lPotentialParam[lSelectedParam].second+1)+ std::string(" node in the ")+uint2ordinal(lPotentialParam[lSelectedParam].first+1)+ std::string(" tree") ); // Mutate parameter value. GP::Primitive::Handle lSelectedPrimit = (*lSelectedTree)[lPotentialParam[lSelectedParam].second].mPrimitive; typename GP::EphemeralT<T>::Handle lSelectedEphemeral = castHandleT<typename GP::EphemeralT<T> >(lSelectedPrimit); GP::Primitive::Handle lGeneratedPrimit = lSelectedEphemeral->generate(mEphemeralName->getWrappedValue(), lContext); (*lSelectedTree)[lPotentialParam[lSelectedParam].second].mPrimitive = lGeneratedPrimit; Beagle_LogVerboseM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationEphemeralOpT", std::string("Changing the ephemeral from ")+lSelectedPrimit->serialize()+ std::string(" to ")+lGeneratedPrimit->serialize() ); // Restore original context values lContext.setGenotypeIndex(lOldGenotypeIndex); lContext.setGenotypeHandle(lOldGenotypeHandle); Beagle_LogDebugM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationEphemeralOpT", "Individual after GP parameters mutation" ); Beagle_LogObjectDebugM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationEphemeralOpT", ioIndividual ); return true; Beagle_StackTraceEndM("bool GP::MutationEphemeralOpT<T>::mutate(Individual& ioIndividual, Context& ioContext)"); }
/*! * \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"); }