/*! * \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 GP::MutationSwapDepthSelectiveConstrainedOp::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; //Select node to mutate unsigned int lChoosenTree = 0; unsigned int lChoosenNode = 0; bool lDoParameterSearch = (lContext.getSystem().getRandomizer().rollUniform(0.0, 1.0) <= mMutParameterPb->getWrappedValue()); RouletteT< std::pair<unsigned int,unsigned int> > lRoulette; //Select primitive based on type for(unsigned int lTry = 0; lTry < 2; ++lTry) { //Do only twice std::vector<const std::type_info*> lDesiredTypes(1, ArgEph); DepthDependentSelectionOp::buildRoulette(lRoulette, lDesiredTypes, lIndividual, lContext,!lDoParameterSearch,lDoParameterSearch); if(lRoulette.size() == 0) { if(lDoParameterSearch) { Beagle_LogVerboseM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationSwapDepthSelectiveConstrainedOp", string("No EphemeralDouble node found.") ); } else { Beagle_LogVerboseM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationSwapDepthSelectiveConstrainedOp", string("No non EphemeralDouble node found.") ); } lDoParameterSearch = !lDoParameterSearch; if(lTry >= 1) { Beagle_LogVerboseM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationSwapDepthSelectiveConstrainedOp", "Unable to GP standard mutate the individual" ); return false; } } else { std::pair<unsigned int,unsigned int> lSelectedNode = lRoulette.select(ioContext.getSystem().getRandomizer()); lChoosenTree = lSelectedNode.first; lChoosenNode = lSelectedNode.second; break; } } if(lDoParameterSearch) { Beagle_LogVerboseM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationSwapDepthSelectiveConstrainedOp", string("Mutation applied only on EphemeralDouble node.") ); } else { Beagle_LogVerboseM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationSwapDepthSelectiveConstrainedOp", string("Mutation applied on node that are not EphemeralDouble.") ); } 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(), "mutation", "Beagle::GP::MutationSwapDepthSelectiveConstrainedOp", std::string("Individual before constrained GP tree swap mutation: ")+ioIndividual.serialize() ); if(lTree.size() > 1) { bool lTypeNode = (lContext.getSystem().getRandomizer().rollUniform(0., 1.) < lDistrProba); //Clean the roulette to include only the choosen tree for(std::vector< std::pair<double, std::pair<unsigned int,unsigned int> > >::iterator lRouletteIter = lRoulette.begin(); lRouletteIter!=lRoulette.end();){ if(lRouletteIter->second.first != lChoosenTree || (lTree[lRouletteIter->second.second].mPrimitive->getNumberArguments() != 0) != lTypeNode ) { lRouletteIter = lRoulette.erase(lRouletteIter++); } else { ++lRouletteIter; } } if(lRoulette.size() > 0) lChoosenNode = lRoulette.select(ioContext.getSystem().getRandomizer()).second; } if( !lDoParameterSearch || lRoulette.size() > 0 ) { Primitive::Handle lOriginalPrimitive = lTree[lChoosenNode].mPrimitive; Beagle_LogVerboseM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationSwapDepthSelectiveConstrainedOp", 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) { Primitive::Handle lChoosenPrimitive = lPrimitiveSet.select(lNbArgsPrimit, lContext); if(lChoosenPrimitive==NULL) break; lTree[lChoosenNode].mPrimitive = lChoosenPrimitive->giveReference(lNbArgsPrimit, lContext); Beagle_LogVerboseM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationSwapDepthSelectiveConstrainedOp", std::string("Trying the primitive \"")+lChoosenPrimitive->getName()+ std::string("\"") ); if(lTree.validateSubTree(lChoosenNode, lContext)) { lMutationDone = true; Beagle_LogVerboseM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationSwapDepthSelectiveConstrainedOp", "Constrained GP tree swap mutation valid" ); break; } else { lTree[lChoosenNode].mPrimitive = lOriginalPrimitive; Beagle_LogVerboseM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationSwapDepthSelectiveConstrainedOp", "Constrained GP tree swap mutation invalid" ); } } } lContext.setGenotypeHandle(lOldTreeHandle); lContext.setGenotypeIndex(lOldTreeIndex); if(lMutationDone) { if( !lDoParameterSearch ) { //Set structure id invalid castHandleT<TreeSTag>((lIndividual)[0])->setStructureIDInvalid(); Beagle_LogVerboseM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationSwapDepthSelectiveConstrainedOp", std::string("Set structure id invalid") ); } Beagle_LogDebugM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationSwapDepthSelectiveConstrainedOp", std::string("Individual after constrained GP swap mutation: ")+ ioIndividual.serialize() ); } else { Beagle_LogVerboseM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationSwapDepthSelectiveConstrainedOp", "Unable to swap mutate the constrained individual" ); } return lMutationDone; Beagle_StackTraceEndM("bool GP::MutationSwapDepthSelectiveConstrainedOp::mutate(Beagle::Individual& ioIndividual, Beagle::Context& ioContext)"); }
/*! * \brief Swap mutate a 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 GP::MutationSwapOp::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(); // Store original values. GP::Tree::Handle lOldTreeHandle = lContext.getGenotypeHandle(); unsigned int lOldTreeIndex = lContext.getGenotypeIndex(); // Select the tree to mutate unsigned int lNbNodes = 0; for(unsigned int i=0; i<lIndividual.size(); i++) lNbNodes += lIndividual[i]->size(); if(lNbNodes == 0) return false; unsigned int lChosenNode = lContext.getSystem().getRandomizer().rollInteger(0, lNbNodes-1); unsigned int lChosenTree = 0; for(; (lChosenTree+1)<lIndividual.size(); lChosenTree++) { if(lChosenNode < lIndividual[lChosenTree]->size()) break; else lChosenNode -= lIndividual[lChosenTree]->size(); } GP::Tree& lTree = *lIndividual[lChosenTree]; if(lTree.size() == 0) return false; // Store the new values lContext.setGenotypeHandle(lIndividual[lChosenTree]); lContext.setGenotypeIndex(lChosenTree); Beagle_LogDebugM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationSwapOp", "Individual before GP swap mutation" ); Beagle_LogObjectDebugM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationSwapOp", ioIndividual ); // Choose the node to mutate. if(lTree.size() > 1) { bool lTypeNode = (lContext.getSystem().getRandomizer().rollUniform(0., 1.) < lDistrProba); while((lTree[lChosenNode].mPrimitive->getNumberArguments() != 0) != lTypeNode) { lChosenNode = lContext.getSystem().getRandomizer().rollInteger(0, lTree.size()-1); } } Primitive::Handle lOriginalPrimitive = lTree[lChosenNode].mPrimitive; Beagle_LogVerboseM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationSwapOp", std::string("Swap mutating the ")+uint2ordinal(lChosenNode+1)+ std::string(" node (primitive: '")+lOriginalPrimitive->getName()+ std::string("' nb args: ")+uint2str(lOriginalPrimitive->getNumberArguments())+ std::string(") of the ")+uint2ordinal(lChosenTree+1)+std::string(" tree") ); GP::PrimitiveSet& lPrimitiveSet = lTree.getPrimitiveSet(lContext); unsigned int lNbArgsPrimit = lTree[lChosenNode].mPrimitive->getNumberArguments(); // Select primitive to replace choosen one. Primitive::Handle lChosenPrimitive = lPrimitiveSet.select(lNbArgsPrimit, lContext); if (lChosenPrimitive==NULL) { Beagle_LogVerboseM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationSwapOp", std::string("Swap mutation failed because no primitive could be found that had ")+ uint2str(lNbArgsPrimit)+std::string(" arguments") ); return false; } else { Beagle_LogDebugM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationSwapOp", std::string("Swap mutation chose primitive '")+lChosenPrimitive->getName()+std::string("'") ); } // Replace choose primitive. lTree[lChosenNode].mPrimitive = lChosenPrimitive->giveReference(lNbArgsPrimit, lContext); // Restore the original values. lContext.setGenotypeHandle(lOldTreeHandle); lContext.setGenotypeIndex(lOldTreeIndex); Beagle_LogDebugM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationSwapOp", "Individual after GP swap mutation" ); Beagle_LogObjectDebugM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationSwapOp", ioIndividual ); return true; Beagle_StackTraceEndM("bool GP::MutationSwapOp::mutate(Beagle::Individual& ioIndividual, Beagle::Context& ioContext)"); }
/*! * \brief Insert mutate a GP individual. * \param ioIndividual GP individual to mutate. * \param ioContext Context of the evolution. * \return True if the individual is effectively mutated, false if not. */ bool GP::MutationInsertConstrainedOp::mutate(Beagle::Individual& ioIndividual, Beagle::Context& ioContext) { Beagle_StackTraceBeginM(); Beagle_LogDetailedM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationInsertConstrainedOp", std::string("Mutating individual with GP::MutationInsertConstrainedOp") ); GP::Individual& lIndividual = castObjectT<GP::Individual&>(ioIndividual); GP::Context& lContext = castObjectT<GP::Context&>(ioContext); const unsigned int lMaxAttempts = mNumberAttempts->getWrappedValue(); const unsigned int lMaxTreeDepth = mMaxTreeDepth->getWrappedValue(); const Factory& lFactory = ioContext.getSystem().getFactory(); GP::Tree::Alloc::Handle lTreeAlloc = castHandleT<GP::Tree::Alloc>(lFactory.getConceptAllocator("Genotype")); // Store original context values const unsigned int lOldGenotypeIndex = lContext.getGenotypeIndex(); const GP::Tree::Handle lOldGenotypeHandle = lContext.getGenotypeHandle(); Beagle_LogDebugM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationInsertConstrainedOp", "Individual before constrained GP insert mutation" ); Beagle_LogObjectDebugM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationInsertConstrainedOp", ioIndividual ); // Mutation attempts loop for(unsigned int i=0; i<lMaxAttempts; ++i) { // Choose tree and node to mutate const unsigned int lChosenTree = lIndividual.chooseRandomTree(lContext); const unsigned int lChosenNodeIndex = lIndividual.chooseRandomNode(lChosenTree, lContext); GP::Tree::Handle lOriginalTree = lIndividual[lChosenTree]; // Compute depth of tree generated by mutation lContext.setGenotypeIndex(lChosenTree); lContext.setGenotypeHandle(lOriginalTree); lContext.emptyCallStack(); lOriginalTree->setContextToNode(lChosenNodeIndex, lContext); const unsigned int lMutationDepth = lContext.getCallStackSize() + lOriginalTree->getTreeDepth(lChosenNodeIndex); // Check that mutation will not generate a tree deeper than the maximum allowed depth if(lMutationDepth > lMaxTreeDepth) { Beagle_LogDebugM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationInsertConstrainedOp", std::string("Constrained insert mutation attempt failed as the generated tree will exceed ")+ std::string("maximum allowed tree depth") ); continue; } // Create new tree Beagle_LogDebugM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationInsertConstrainedOp", std::string("Creating new tree") ); GP::Tree::Handle lNewTree = castHandleT<GP::Tree>(lTreeAlloc->allocate()); lNewTree->setPrimitiveSetIndex(lOriginalTree->getPrimitiveSetIndex()); lNewTree->setNumberArguments(lOriginalTree->getNumberArguments()); // Replace original tree with new tree lIndividual[lChosenTree] = lNewTree; lContext.setGenotypeHandle(lNewTree); // Copy unchanged part of original tree into new tree Beagle_LogDebugM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationInsertConstrainedOp", std::string("Copying unchanged part of original tree to new tree") ); lNewTree->insert(lNewTree->end(), lOriginalTree->begin(), lOriginalTree->begin()+lChosenNodeIndex); Beagle_AssertM(lNewTree->size() == lChosenNodeIndex); // Generate new branch primitive to insert. GP::PrimitiveSet& lPrimitiveSet = lNewTree->getPrimitiveSet(lContext); Primitive::Handle lBranchInserted = lPrimitiveSet.select(GP::Primitive::eBranch, lContext); if(lBranchInserted==NULL) { Beagle_LogDebugM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationInsertConstrainedOp", std::string("Constrained insert mutation attempt failed as it seems impossible ")+ std::string("to select a branch primitive in the actual context") ); lIndividual[lChosenTree] = lOriginalTree; lContext.setGenotypeHandle(lOriginalTree); continue; } Beagle_LogDebugM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationInsertConstrainedOp", std::string("Branch primitive to be inserted by mutation is primitive '")+ lBranchInserted->getName()+std::string("'") ); // Insert new branch lBranchInserted = lBranchInserted->giveReference(GP::Primitive::eBranch, lContext); lNewTree->push_back(Node(lBranchInserted,1)); if(lBranchInserted->validate(lContext) == false) { Beagle_LogDebugM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationInsertConstrainedOp", std::string("Constrained insert mutation attempt failed as the selected ")+ std::string("branch doesn't match the constraints") ); lIndividual[lChosenTree] = lOriginalTree; lContext.setGenotypeHandle(lOriginalTree); continue; } const unsigned int lNbArgsInsertedBranch = lBranchInserted->getNumberArguments(); Beagle_AssertM(lNbArgsInsertedBranch != 0); const unsigned int lSubtreeArgIndex = lContext.getSystem().getRandomizer().rollInteger(0, lNbArgsInsertedBranch-1); Beagle_AssertM(lSubtreeArgIndex < lNbArgsInsertedBranch); const unsigned int lSubtreeSize = (*lOriginalTree)[lChosenNodeIndex].mSubTreeSize; // Generate inserted node subtrees bool lArgsGenFailed = false; for(unsigned int j=0; j<lNbArgsInsertedBranch; ++j) { if(j == lSubtreeArgIndex) { const unsigned int lSubtreeIndex = lNewTree->size(); lNewTree->insert(lNewTree->end(), lOriginalTree->begin()+lChosenNodeIndex, lOriginalTree->begin()+lChosenNodeIndex+lSubtreeSize); lContext.pushCallStack(lSubtreeIndex); if(lNewTree->validateSubTree(lSubtreeIndex, lContext) == false) { lArgsGenFailed = true; break; } lContext.popCallStack(); (*lNewTree)[lChosenNodeIndex].mSubTreeSize += lSubtreeSize; } else { Primitive::Handle lArgInserted = lPrimitiveSet.select(GP::Primitive::eTerminal, lContext); if(lArgInserted == NULL) { lArgsGenFailed = true; break; } lArgInserted = lArgInserted->giveReference(GP::Primitive::eTerminal, lContext); const unsigned int lSubtreeIndex = lNewTree->size(); lNewTree->push_back(Node(lArgInserted,1)); lContext.pushCallStack(lSubtreeIndex); if(lArgInserted->validate(lContext) == false) { lArgsGenFailed = true; break; } lContext.popCallStack(); ++(*lNewTree)[lChosenNodeIndex].mSubTreeSize; } } if(lArgsGenFailed) { Beagle_LogDebugM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationInsertConstrainedOp", std::string("Constrained insert mutation attempt failed as it seems impossible ")+ std::string("to select a terminal primitive under the inserted branch in the actual context") ); lIndividual[lChosenTree] = lOriginalTree; lContext.setGenotypeHandle(lOriginalTree); continue; } // Complete new tree with rest of original tree Beagle_AssertM(lOriginalTree->size() >= (lChosenNodeIndex+lSubtreeSize)); lNewTree->insert(lNewTree->end(), lOriginalTree->begin()+lChosenNodeIndex+lSubtreeSize, lOriginalTree->end()); Beagle_AssertM(lNewTree->size() == (lOriginalTree->size()+lNbArgsInsertedBranch)); // Correct subtree size data and terminate mutation process Beagle_LogDebugM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationInsertConstrainedOp", std::string("Correcting the 'mSubTreeSize' fields of tree") ); lContext.popCallStack(); for(unsigned int j=0; j<lContext.getCallStackSize(); ++j) { (*lNewTree)[lContext[j]].mSubTreeSize += lNbArgsInsertedBranch; } // Mutation successful, log messages and return std::ostringstream lOSS; lOSS << "Successfully inserted a new node at index " << lChosenNodeIndex; lOSS << " of the " << uint2ordinal(lChosenTree) << " tree of the actual individual"; Beagle_LogTraceM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationInsertConstrainedOp", lOSS.str() ); Beagle_LogDebugM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationInsertConstrainedOp", "Individual after constrained GP insert mutation" ); Beagle_LogObjectDebugM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationInsertConstrainedOp", ioIndividual ); lContext.emptyCallStack(); lContext.setGenotypeIndex(lOldGenotypeIndex); lContext.setGenotypeHandle(lOldGenotypeHandle); return true; } // Insert mutation failed, return without mutating the individual lContext.emptyCallStack(); lContext.setGenotypeIndex(lOldGenotypeIndex); lContext.setGenotypeHandle(lOldGenotypeHandle); Beagle_LogTraceM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationInsertConstrainedOp", std::string("All constrained insert mutation attempts failed; ")+ std::string("resuming from mutation without modifying the individual") ); return false; Beagle_StackTraceEndM("bool GP::MutationInsertConstrainedOp::mutate(Beagle::Individual& ioIndividual, Beagle::Context& ioContext)"); }
/*! * \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 GP::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(), "mutation", "Beagle::GP::MutationSwapConstrainedOp", "Individual before constrained GP tree swap mutation" ); Beagle_LogObjectDebugM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationSwapConstrainedOp", 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); } } Primitive::Handle lOriginalPrimitive = lTree[lChoosenNode].mPrimitive; Beagle_LogVerboseM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationSwapConstrainedOp", 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) { Primitive::Handle lChoosenPrimitive = lPrimitiveSet.select(lNbArgsPrimit, lContext); if(lChoosenPrimitive==NULL) break; lTree[lChoosenNode].mPrimitive = lChoosenPrimitive->giveReference(lNbArgsPrimit, lContext); Beagle_LogVerboseM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationSwapConstrainedOp", std::string("Trying the primitive '")+lChoosenPrimitive->getName()+ std::string("'") ); if(lTree.validateSubTree(lChoosenNode, lContext)) { lMutationDone = true; Beagle_LogVerboseM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationSwapConstrainedOp", "Constrained GP tree swap mutation valid" ); break; } else { lTree[lChoosenNode].mPrimitive = lOriginalPrimitive; Beagle_LogVerboseM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationSwapConstrainedOp", "Constrained GP tree swap mutation invalid" ); } } lContext.setGenotypeHandle(lOldTreeHandle); lContext.setGenotypeIndex(lOldTreeIndex); if(lMutationDone) { Beagle_LogDebugM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationSwapConstrainedOp", "Individual after constrained GP swap mutation" ); Beagle_LogObjectDebugM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationSwapConstrainedOp", ioIndividual ); } else { Beagle_LogVerboseM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationSwapConstrainedOp", "Unable to swap mutate the constrained individual" ); } return lMutationDone; Beagle_StackTraceEndM("bool GP::MutationSwapConstrainedOp::mutate(Beagle::Individual& ioIndividual, Beagle::Context& ioContext)"); }