/* * 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 * */ #include "beagle/GP.hpp" using namespace Beagle; /*! * \brief Construct a plain new initialization operator. * \param inReproProbaName Reproduction probability parameter name used in register. * \param inName Name of the initialization operator. */ GP::InitializationOp::InitializationOp(Beagle::string inReproProbaName, Beagle::string inName) : Beagle::InitializationOp(inReproProbaName, inName) { } /*! * \brief Initialize the generic GP intialization operator. * \param ioSystem System of the evolution. */ void GP::InitializationOp::initialize(Beagle::System& ioSystem) { Beagle_StackTraceBeginM(); Beagle::InitializationOp::initialize(ioSystem); if(ioSystem.getRegister().isRegistered("gp.init.maxdepth")) { mMaxTreeDepth = castHandleT(ioSystem.getRegister()["gp.init.maxdepth"]); } else { mMaxTreeDepth = new UInt(5); Register::Description lDescription( "Maximum initial tree depth", "UInt", "5", "Maximum depth for newly initialized trees." ); ioSystem.getRegister().addEntry("gp.init.maxdepth", mMaxTreeDepth, lDescription); } if(ioSystem.getRegister().isRegistered("gp.init.mindepth")) { mMinTreeDepth = castHandleT(ioSystem.getRegister()["gp.init.mindepth"]); } else { mMinTreeDepth = new UInt(2); Register::Description lDescription( "Minimum initial tree depth", "UInt", "2", "Minimum depth for newly initialized trees." ); ioSystem.getRegister().addEntry("gp.init.mindepth", mMinTreeDepth, lDescription); } if(ioSystem.getRegister().isRegistered("gp.init.maxtree")) { mMaxNumberTrees = castHandleT(ioSystem.getRegister()["gp.init.maxtree"]); } else { mMaxNumberTrees = new UInt(1); Register::Description lDescription( "Maximum number of trees", "UInt", "1", string("Maximum number of GP tree in newly initialized individuals. More than one tree ")+ string("is usually useful with ADFs (and other ADx).") ); ioSystem.getRegister().addEntry("gp.init.maxtree", mMaxNumberTrees, lDescription); } if(ioSystem.getRegister().isRegistered("gp.init.mintree")) { mMinNumberTrees = castHandleT(ioSystem.getRegister()["gp.init.mintree"]); } else { mMinNumberTrees = new UInt(1); Register::Description lDescription( "Minimum number of trees", "UInt", "1", string("Minimum number of GP tree in newly initialized individuals. More than one tree ")+ string("is usually useful with ADFs (and other ADx).") ); ioSystem.getRegister().addEntry("gp.init.mintree", mMinNumberTrees, lDescription); } if(ioSystem.getRegister().isRegistered("gp.tree.maxargs")) { mMaxTreeArgs = castHandleT(ioSystem.getRegister()["gp.tree.maxargs"]); } else { mMaxTreeArgs = new UIntArray; mMaxTreeArgs->push_back(0); mMaxTreeArgs->push_back(2); Register::Description lDescription( "Max. number of tree arguments", "UIntArray", "0/2", string("Maximum number of arguments in GP tree. Tree arguments are ")+ string("is usually useful with ADFs (and similar stuff).") ); ioSystem.getRegister().addEntry("gp.tree.maxargs", mMaxTreeArgs, lDescription); } if(ioSystem.getRegister().isRegistered("gp.tree.minargs")) { mMinTreeArgs = castHandleT(ioSystem.getRegister()["gp.tree.minargs"]); } else { mMinTreeArgs = new UIntArray; mMinTreeArgs->push_back(0); mMinTreeArgs->push_back(2); Register::Description lDescription( "Min. number of tree arguments", "UIntArray", "0/2", string("Minimum number of arguments in GP tree. Tree arguments are ")+ string("is usually useful with ADFs a(nd similar stuff).") ); ioSystem.getRegister().addEntry("gp.tree.minargs", mMinTreeArgs, lDescription); } Beagle_StackTraceEndM("void GP::InitializationOp::initialize(Beagle::System& ioSystem)"); } /*! * \brief Initialize the trees of an individual. * \param outIndividual Individual to initialize. * \param ioContext Evolution context. * \throw Beagle::RunTimeException If the min/max depths are incorrectly set. */ void GP::InitializationOp::initIndividual(Beagle::Individual& outIndividual, Beagle::Context& ioContext) { Beagle_StackTraceBeginM(); #ifndef BEAGLE_NDEBUG if (mMinTreeDepth==NULL || mMaxTreeDepth==NULL) throw Beagle_RunTimeExceptionM(string("GP::InitializationOp has not been initialized."). append(" Consider the GP::InitializationOp::initialize() method.")); if(*mMinTreeDepth > *mMaxTreeDepth) { string lMessage = "GP::InitializationOp::initIndividual: Minimum tree depth is superior "; lMessage += "to the maximum tree depth. Could not initialize the individuals!"; throw Beagle::ValidationException(lMessage); } #endif // BEAGLE_NDEBUG Beagle_ValidateParameterM(mMinTreeDepth->getWrappedValue()>0,"gp.init.mindepth",">0"); GP::Individual& lIndividual = castObjectT(outIndividual); GP::Context& lContext = castObjectT(ioContext); const unsigned int lPrimitiveSuperSetSize = lContext.getSystem().getPrimitiveSuperSet().size(); #ifndef BEAGLE_NDEBUG if(lPrimitiveSuperSetSize == 0) throw Beagle_RunTimeExceptionM(string("GP::InitializationOp::initIndividual(): There "). append(" are no PrimitiveSets in the PrimitiveSuperSet. There needs to be at least one"). append(" PrimitiveSet. See the examples that are included with Beagle to learn how"). append(" to create a PrimitiveSet, add Primitives to it, and then construct a System based"). append(" on the PrimitiveSet.")); #endif // BEAGLE_NDEBUG // Choose randomly the number of individuals in tree const unsigned int lMaxDepth = mMaxTreeDepth->getWrappedValue(); const unsigned int lMinDepth = mMinTreeDepth->getWrappedValue(); const unsigned int lMaxNbTrees = mMaxNumberTrees->getWrappedValue(); const unsigned int lMinNbTrees = mMinNumberTrees->getWrappedValue(); Beagle_AssertM(lMaxNbTrees >= lMinNbTrees); const unsigned int lNbTrees = ioContext.getSystem().getRandomizer().rollInteger(lMinNbTrees,lMaxNbTrees); lIndividual.resize(lNbTrees); GP::Tree::Handle lOldTreeHandle = lContext.getGenotypeHandle(); unsigned int lOldTreeIndex = lContext.getGenotypeIndex(); for(unsigned int i=0; isetPrimitiveSetIndex(i); else lIndividual[i]->setPrimitiveSetIndex(lPrimitiveSuperSetSize-1); const unsigned int lMaxArgs = (isize()) ? (*mMaxTreeArgs)[i] : mMaxTreeArgs->back(); const unsigned int lMinArgs = (isize()) ? (*mMinTreeArgs)[i] : mMinTreeArgs->back(); Beagle_AssertM(lMaxArgs >= lMinArgs); const unsigned int lNbArgs = ioContext.getSystem().getRandomizer().rollInteger(lMinArgs,lMaxArgs); lIndividual[i]->setNumberArguments(lNbArgs); } for(unsigned int i=0; i