mutationswapsubtreeop.cpp
来自「非常好的进化算法EC 实现平台 可以实现多种算法 GA GP」· C++ 代码 · 共 478 行 · 第 1/2 页
CPP
478 行
/* * Open BEAGLE * Copyright (C) 2001-2005 by Christian Gagne and Marc Parizeau * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Contact: * Laboratoire de Vision et Systemes Numeriques * Departement de genie electrique et de genie informatique * Universite Laval, Quebec, Canada, G1K 7P4 * http://vision.gel.ulaval.ca * *//*! * \file beagle/GP/src/MutationSwapSubtreeOp.cpp * \brief Source code of class GP::MutationSwapSubtreeOp. * \author Christian Gagne <cgagne@gmail.com> * \author Jianjun Hu <hujianju@msu.edu> * \author Marc Parizeau <parizeau@gel.ulaval.ca> * $Revision: 1.11 $ * $Date: 2005/10/04 16:25:10 $ */#include "beagle/GP.hpp"#include <algorithm>#include <string>using namespace Beagle;/*! * \brief Construct a GP swap subtree mutation operator. * \param inMutationPbName Mutation probability parameter name used in register. * \param inDistribPbName Swap mutation distribution probability parameter name. * \param inName Name of the operator. */GP::MutationSwapSubtreeOp::MutationSwapSubtreeOp(Beagle::string inMutationPbName, Beagle::string inDistribPbName, Beagle::string inName) : Beagle::MutationOp(inMutationPbName, inName), mDistribPbName(inDistribPbName){ }/*! * \brief Initialize the GP swap subtree mutation operator. * \param ioSystem System of the evolution. */void GP::MutationSwapSubtreeOp::initialize(Beagle::System& ioSystem){ Beagle_StackTraceBeginM(); Beagle::MutationOp::initialize(ioSystem); if(ioSystem.getRegister().isRegistered(mMutationPbName)) { ioSystem.getRegister().deleteEntry(mMutationPbName); } if(ioSystem.getRegister().isRegistered(mMutationPbName)) { mMutationProba = castHandleT<Float>(ioSystem.getRegister()[mMutationPbName]); } else { mMutationProba = new Float(float(0.0)); string lLongDescrip = "Swap subtree mutation probability for an individual. "; lLongDescrip += "A swap subtree mutation consists to swap two subtrees of a tree in an "; lLongDescrip += "individual."; Register::Description lProbaDescription( "Swap subtree mutation prob.", "Float", "0.0", lLongDescrip ); ioSystem.getRegister().addEntry(mMutationPbName, mMutationProba, lProbaDescription); } if(ioSystem.getRegister().isRegistered(mDistribPbName)) { mDistributionProba = castHandleT<Float>(ioSystem.getRegister()[mDistribPbName]); } else { mDistributionProba = new Float(float(0.5)); string lLongDescrip = "Probability that a swap subtree is internal "; lLongDescrip += "(the mutation occurs between three points, where the 2nd point is in the "; lLongDescrip += "1st point's subtree, and the 3rd point is in the 2nd point's subtree) vs "; lLongDescrip += "being external (the mutation occurs between two points, "; lLongDescrip += "where both points are not within the other's subtree). "; lLongDescrip += "Value of 1.0 means that the swap subtrees mutations are all internal "; lLongDescrip += "while value of 0.0 means that swap subtrees mutations are all external."; Register::Description lDescription( "Swap subtree mut. distrib. prob.", "Float", "0.5", lLongDescrip ); ioSystem.getRegister().addEntry(mDistribPbName, mDistributionProba, lDescription); } if(ioSystem.getRegister().isRegistered("gp.tree.maxdepth")) { mMaxTreeDepth = castHandleT<UInt>(ioSystem.getRegister()["gp.tree.maxdepth"]); } else { mMaxTreeDepth = new UInt(17); Register::Description lDescription( "Maximum tree depth", "UInt", "17", "Maximum allowed depth for the trees." ); ioSystem.getRegister().addEntry("gp.tree.maxdepth", mMaxTreeDepth, lDescription); } if(ioSystem.getRegister().isRegistered("gp.try")) { mNumberAttempts = castHandleT<UInt>(ioSystem.getRegister()["gp.try"]); } else { mNumberAttempts = new UInt(2); string lLongDescrip = "Maximum number of attempts to modify a GP tree in a genetic "; lLongDescrip += "operation. As there is topological constraints on GP trees (i.e. tree "; lLongDescrip += "depth limit), it is often necessary to try a genetic operation several times."; Register::Description lDescription( "Max number of attempts", "UInt", "2", lLongDescrip ); ioSystem.getRegister().addEntry("gp.try", mNumberAttempts, lDescription); } Beagle_StackTraceEndM("void GP::MutationSwapSubtreeOp::initialize(Beagle::System& ioSystem)");}/*! * \brief Swap subtree mutate a GP individual. * \param ioIndividual GP individual to swap subtree mutate. * \param ioContext Context of the evolution. */bool GP::MutationSwapSubtreeOp::mutate(Beagle::Individual& ioIndividual, Beagle::Context& ioContext){ Beagle_StackTraceBeginM(); // Initial parameters checks. Beagle_AssertM(ioIndividual.size() > 0); Beagle_ValidateParameterM(mNumberAttempts->getWrappedValue()>0, "gp.try", ">0"); // Cast method arguments. GP::Individual& lGPIndiv = castObjectT<GP::Individual&>(ioIndividual); GP::Context& lContext1 = castObjectT<GP::Context&>(ioContext); GP::Context::Alloc& lContextAlloc = castObjectT<GP::Context::Alloc&>(ioContext.getSystem().getContextAllocator()); GP::Context::Handle lContextHdl2 = castHandleT<GP::Context>(lContextAlloc.clone(lContext1)); // Get parameters in local values, with the total number of nodes of the mutated individual. bool lMatingDone = false; float lDistrProba = mDistributionProba->getWrappedValue(); unsigned int lMaxTreeDepth = mMaxTreeDepth->getWrappedValue(); GP::Tree::Handle lOldTreeHandle1 = lContext1.getGenotypeHandle(); unsigned int lOldTreeIndex1 = lContext1.getGenotypeIndex(); unsigned int lSizeIndiv = 0; for(unsigned int i=0; i<lGPIndiv.size(); ++i) lSizeIndiv += lGPIndiv[i]->size(); // Some outputs. Beagle_LogDebugM( lContext1.getSystem().getLogger(), "mutation", "Beagle::GP::MutationSwapSubtreeOp", string("Individual tried for swap subtree mutation (before): ")+ lGPIndiv.serialize() ); // Mutation loop. Try the given number of attempts to mutation the individual. for(unsigned int lAttempt=0; lAttempt < mNumberAttempts->getWrappedValue(); lAttempt++) { // Calculate the number of nodes in the individual unsigned int lNbNodes = 0; for(unsigned int i=0; i<lGPIndiv.size(); i++) lNbNodes += lGPIndiv[i]->size(); if(lNbNodes == 0) return false; // Choose a node of the individual to mutate. unsigned int lNode1 = lContext1.getSystem().getRandomizer().rollInteger(0, lNbNodes-1); // Get the tree in which the choosen node is. Change the global node index to the tree's index. unsigned int lChoosenTree = 0; for(; lChoosenTree<lGPIndiv.size(); ++lChoosenTree) { if(lNode1 < lGPIndiv[lChoosenTree]->size()) break; Beagle_AssertM(lNode1 >= lGPIndiv[lChoosenTree]->size()); lNode1 -= lGPIndiv[lChoosenTree]->size(); } Beagle_AssertM(lChoosenTree < lGPIndiv.size()); // Cannot do anything with an tree of size <= 1. if(lGPIndiv[lChoosenTree]->size() <= 1) continue; // Some outputs. Beagle_LogVerboseM( lContext1.getSystem().getLogger(), "mutation", "Beagle::GP::MutationSwapSubtreeOp", string("Trying a swap subtree mutation of the ")+uint2ordinal(lChoosenTree+1)+ string(" tree") ); // Make two clones of the choosen tree. GP::Tree::Alloc& lTreeAlloc = castObjectT<GP::Tree::Alloc&>(*lGPIndiv.getTypeAlloc()); GP::Tree::Handle lTreeClone1 = castHandleT<GP::Tree>(lTreeAlloc.clone(*lGPIndiv[lChoosenTree])); GP::Tree::Handle lTreeClone2 = castHandleT<GP::Tree>(lTreeAlloc.clone(*lGPIndiv[lChoosenTree])); // Now we decide whether the swap subtree mutation is internal or external. bool lMutationType = lContext1.getSystem().getRandomizer().rollUniform(0.0, 1.0) < lDistrProba; // Cannot do an internal mutation when there is only one branch in the tree. if(lTreeClone1->size() == (*lTreeClone1)[0].mPrimitive->getNumberArguments()+1) lMutationType = false; // This is special case, a linear tree. Cannot do an external mutation. if(lTreeClone1->size() == (*lTreeClone1)[1].mSubTreeSize+1) { if(lTreeClone1->size()==2) continue; // Cannot do anything here with the tree. lMutationType = true; } // lMutationType is true -> internal mutation if(lMutationType) { // If the selected node is a terminal, or a branch with a subtree made only of terminals, // choose another node in the same tree. while((*lTreeClone1)[lNode1].mSubTreeSize == ((*lTreeClone1)[lNode1].mPrimitive->getNumberArguments()+1)) { lNode1 = lContext1.getSystem().getRandomizer().rollInteger(0, lTreeClone1->size()-1); } // Choosing the second node, a branch in lNode1's subtree. unsigned int lSubTreeSizeN1 = (*lTreeClone1)[lNode1].mSubTreeSize; unsigned int lN2OffN1 = lContext1.getSystem().getRandomizer().rollInteger(1, lSubTreeSizeN1-1); unsigned int lNode2 = lNode1 + lN2OffN1; while((*lTreeClone1)[lNode2].mPrimitive->getNumberArguments() == 0) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?