/* * 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/GA/src/CrossoverIndicesIntVecOp.cpp * \brief Source code of class GA::CrossoverIndicesIntVecOp. * \author Christian Gagne * \author Marc Parizeau * $Revision: 1.3 $ * $Date: 2005/09/30 15:04:53 $ */ #include "beagle/GA.hpp" #include #include using namespace Beagle; /*! * \brief Construct a indices integer vector crossover operator. * \param inMatingPbName Mating probability parameter name. * \param inName Name of the operator. */ Beagle::GA::CrossoverIndicesIntVecOp::CrossoverIndicesIntVecOp(string inMatingPbName, string inName) : CrossoverOp(inMatingPbName, inName) { } /*! * \brief Initialize the indices integer vector operator. * \param ioSystem System of the evolution. */ void Beagle::GA::CrossoverIndicesIntVecOp::initialize(Beagle::System& ioSystem) { Beagle_StackTraceBeginM(); CrossoverOp::initialize(ioSystem); if(ioSystem.getRegister().isRegistered(mMatingProbaName)) { ioSystem.getRegister().deleteEntry(mMatingProbaName); } if(ioSystem.getRegister().isRegistered(mMatingProbaName)) { mMatingProba = castHandleT(ioSystem.getRegister()[mMatingProbaName]); } else { mMatingProba = new Float(float(0.3)); Register::Description lDescription( "Indices int. crossover prob.", "Float", "0.3", "Indices integer vector crossover probability of a single individual." ); ioSystem.getRegister().addEntry(mMatingProbaName, mMatingProba, lDescription); } Beagle_StackTraceEndM("void GA::CrossoverIndicesIntVecOp::initialize(System& ioSystem)"); } /*! * \brief Mate two GA individuals for indices integer vector crossover. * \param ioIndiv1 First individual to mate. * \param ioContext1 Evolutionary context of the first individual. * \param ioIndiv2 Second individual to mate. * \param ioContext2 Evolutionary context of the second individual. * \return True if the individuals are effectively mated, false if not. */ bool Beagle::GA::CrossoverIndicesIntVecOp::mate(Beagle::Individual& ioIndiv1, Beagle::Context& ioContext1, Beagle::Individual& ioIndiv2, Beagle::Context& ioContext2) { Beagle_StackTraceBeginM(); unsigned int lNbGenotypes = minOf(ioIndiv1.size(), ioIndiv2.size()); if(lNbGenotypes==0) return false; Beagle_LogDebugM( ioContext1.getSystem().getLogger(), "crossover", "Beagle::GA::CrossoverIndicesIntVecOp", string("The first individual mated is (before indices integer vector crossover): ")+ ioIndiv1.serialize() ); Beagle_LogDebugM( ioContext1.getSystem().getLogger(), "crossover", "Beagle::GA::CrossoverIndicesIntVecOp", string("The second individual mated is (before indices integer vector crossover): ")+ ioIndiv2.serialize() ); for(unsigned int i=0; i(ioIndiv1[i]); std::deque< int,BEAGLE_STLALLOCATOR > lIntVecCopy1(lIntVector1->begin(), lIntVector1->end()); std::vector< bool,BEAGLE_STLALLOCATOR > lSelected1(lIntVecCopy1.size(), false); GA::IntegerVector::Handle lIntVector2 = castHandleT(ioIndiv2[i]); std::deque< int,BEAGLE_STLALLOCATOR > lIntVecCopy2(lIntVector2->begin(), lIntVector2->end()); std::vector< bool,BEAGLE_STLALLOCATOR > lSelected2(lIntVecCopy2.size(), false); const unsigned int lSumSize = lIntVector1->size() + lIntVector2->size(); unsigned int lCount1=0; unsigned int lCount2=0; while((lIntVecCopy1.empty()==false) || (lIntVecCopy2.empty()==false)) { // Get next selected index. unsigned int lSelectedIndex=0; if(lIntVecCopy1.empty()) { lSelectedIndex=lIntVecCopy2.front(); lIntVecCopy2.pop_front(); } else if(lIntVecCopy2.empty()) { lSelectedIndex=lIntVecCopy1.front(); lIntVecCopy1.pop_front(); } else { if(ioContext1.getSystem().getRandomizer().rollInteger(0,lSumSize-1) >= lIntVector1->size()) { lSelectedIndex=lIntVecCopy2.front(); lIntVecCopy2.pop_front(); } else { lSelectedIndex=lIntVecCopy1.front(); lIntVecCopy1.pop_front(); } } // Insert selected index in appropriate integer vector. if((lSelectedIndex>=lIntVector1->size()) || lSelected1[lSelectedIndex]) { Beagle_AssertM(lSelectedIndexsize()); Beagle_AssertM(lSelected2[lSelectedIndex]==false); Beagle_AssertM(lCount2size()); (*lIntVector2)[lCount2++] = lSelectedIndex; lSelected2[lSelectedIndex] = true; } else if((lSelectedIndex>=lIntVector2->size()) || lSelected2[lSelectedIndex]) { Beagle_AssertM(lCount1size()); (*lIntVector1)[lCount1++] = lSelectedIndex; lSelected1[lSelectedIndex] = true; } else if(ioContext1.getSystem().getRandomizer().rollUniform(0.0,1.0) >= 0.5) { Beagle_AssertM(lCount1size()); (*lIntVector1)[lCount1++] = lSelectedIndex; lSelected1[lSelectedIndex] = true; } else { Beagle_AssertM(lCount2size()); (*lIntVector2)[lCount2++] = lSelectedIndex; lSelected2[lSelectedIndex] = true; } } } Beagle_LogDebugM( ioContext1.getSystem().getLogger(), "crossover", "Beagle::GA::CrossoverIndicesIntVecOp", string("The first individual mated is (after indices integer vector crossover): ")+ ioIndiv1.serialize() ); Beagle_LogDebugM( ioContext1.getSystem().getLogger(), "crossover", "Beagle::GA::CrossoverIndicesIntVecOp", string("The second individual mated is (after indices integer vector crossover): ")+ ioIndiv2.serialize() ); return true; Beagle_StackTraceEndM("bool GA::CrossoverIndicesIntVecOp::mate(Individual& ioIndiv1, Context& ioContext1, Individual& ioIndiv2, Context& ioContext2)"); }