# make_op_MyStruct.h

    00001 // -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
    00002
    00003 //-----------------------------------------------------------------------------
    00004 // make_op_MyStruct.h
    00005 // (c) Marc Schoenauer, Maarten Keijzer and GeNeura Team, 2001
    00006 /*
    00007     This library is free software; you can redistribute it and/or
    00008     modify it under the terms of the GNU Lesser General Public
    00009     License as published by the Free Software Foundation; either
    00010     version 2 of the License, or (at your option) any later version.
    00011
    00012     This library is distributed in the hope that it will be useful,
    00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
    00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00015     Lesser General Public License for more details.
    00016
    00017     You should have received a copy of the GNU Lesser General Public
    00018     License along with this library; if not, write to the Free Software
    00019     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    00020
    00021     Contact: todos@geneura.ugr.es, http://geneura.ugr.es
    00022              Marc.Schoenauer@polytechnique.fr
    00023              mkeijzer@dhi.dk
    00024  */
    00025 //-----------------------------------------------------------------------------
    00026
    00027 #ifndef _make_op_MyStruct_h
    00028 #define _make_op_MyStruct_h
    00029
    00030 // the operators
    00031 #include <eoOp.h>
    00032 #include <eoGenOp.h>
    00033 #include <eoCloneOps.h>
    00034 #include <eoOpContainer.h>
    00035 // combinations of simple eoOps (eoMonOp and eoQuadOp)
    00036 #include <eoProportionalCombinedOp.h>
    00037
    00041 #include "eoMyStructMutation.h"
    00042
    00048 // #include "eoMyStructBinOp.h"
    00049 // OR
    00050 #include "eoMyStructQuadCrossover.h"
    00051
    00052   // also need the parser and state includes
    00053 #include <utils/eoParser.h>
    00054 #include <utils/eoState.h>
    00055
    00056
    00058 // canonical (crossover + mutation) only at the moment //
    00059
    00060 /*
    00061  * This function builds the operators that will be applied to the eoMyStruct
    00062  *
    00063  * It uses a parser (to get user parameters), a state (to store the memory)
    00064  *    the last parameter is an eoInit: if some operator needs some info
    00065  *    about the genotypes, the init has it all (e.g. bounds, ...)
    00066  *    Simply do
    00067  *        EOT myEO;
    00068  *        _init(myEO);
    00069  *    and myEO is then an ACTUAL object
    00070  *
    00071  * As usual, the template is the complete EOT even though only the fitness
    00072  * is actually templatized here: the following only applies to eoMyStruct
    00073 */
    00074
    00075 template <class EOT>
    00076 eoGenOp<EOT> & do_make_op(eoParameterLoader& _parser, eoState& _state, eoInit<EOT>& _init)
    00077 {
    00078   // this is a temporary version, while Maarten codes the full tree-structured
    00079   // general operator input
    00080   // BTW we must leave that simple version available somehow, as it is the one
    00081   // that 90% people use!
    00082
    00083
    00085     // Variation operators
    00087     // read crossover and mutations, combine each in a proportional Op
    00088     // and create the eoGenOp that calls crossover at rate pCross
    00089     // then mutation with rate pMut
    00090
    00091     // the crossovers
    00093
    00094     // here we can have eoQuadOp (2->2) only - no time for the eoBinOp case
    00095
    00096     // you can have more than one - combined in a proportional way
    00097
    00098     // first, define the crossover objects and read their rates from the parser
    00099
    00100     // A first crossover
    00101     eoQuadOp<Indi> *cross = new eoMyStructQuadCrossover<Indi> /* (varType  _anyVariable) */;
    00102     // store in the state
    00103     _state.storeFunctor(cross);
    00104
    00105   // read its relative rate in the combination
    00106     double cross1Rate = _parser.createParam(1.0, "cross1Rate", "Relative rate for crossover 1", '1', "Variation Operators").value();
    00107
    00108   // and create the combined operator with this one
    00109   eoPropCombinedQuadOp<Indi> *propXover =
    00110     new eoPropCombinedQuadOp<Indi>(*cross, cross1Rate);
    00111   // and of course stor it in the state
    00112     _state.storeFunctor(propXover);
    00113
    00114
    00115     // Optional: A second(and third, and ...)  crossover
    00116     //   of course you must create the corresponding classes
    00117     // and all ***MUST*** derive from eoQuadOp<Indi>
    00118
    00119   /* Uncomment if necessary - and replicate as many time as you need
    00120       cross = new eoMyStructSecondCrossover<Indi>(varType  _anyVariable);
    00121       _state.storeFunctor(cross);
    00122       double cross2Rate = _parser.createParam(1.0, "cross2Rate", "Relative rate for crossover 2", '2', "Variation Operators").value();
    00123       propXover.add(*cross, cross2Rate);
    00124   */
    00125   // if you want some gentle output, the last one shoudl be like
    00126   //  propXover.add(*cross, crossXXXRate, true);
    00127
    00128
    00129   // the mutation: same story
    00131   // you can have more than one - combined in a proportional way
    00132
    00133   // for each mutation,
    00134   // - define the mutator object
    00135   // - read its rate from the parser
    00136   // - add it to the proportional combination
    00137
    00138   // a first mutation
    00139   eoMonOp<Indi> *mut = new eoMyStructMutation<Indi>/* (varType  _anyVariable) */;
    00140   _state.storeFunctor(mut);
    00141   // its relative rate in the combination
    00142   double mut1Rate = _parser.createParam(1.0, "mut1Rate", "Relative rate for mutation 1", '1', "Variation Operators").value();
    00143   // and the creation of the combined operator with this one
    00144   eoPropCombinedMonOp<Indi> *propMutation = new eoPropCombinedMonOp<Indi>(*mut, mut1Rate);
    00145   _state.storeFunctor(propMutation);
    00146
    00147     // Optional: A second(and third, and ...)  mutation with their rates
    00148     //   of course you must create the corresponding classes
    00149     // and all ***MUST*** derive from eoMonOp<Indi>
    00150
    00151   /* Uncomment if necessary - and replicate as many time as you need
    00152       mut = new eoMyStructSecondMutation<Indi>(varType  _anyVariable);
    00153       _state.storeFunctor(mut);
    00154       double mut2Rate = _parser.createParam(1.0, "mut2Rate", "Relative rate for mutation 2", '2', "Variation Operators").value();
    00155        propMutation.add(*mut, mut2Rate);
    00156   */
    00157   // if you want some gentle output, the last one shoudl be like
    00158   //  propMutation.add(*mut, mutXXXRate, true);
    00159
    00160   // end of crossover and mutation definitions
    00162
    00163 // END Modify definitions of objects by eventually add parameters
    00164 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
    00165
    00166 // from now on, you do not need to modify anything
    00167 // though you CAN add things to the checkpointing (see tutorial)
    00168
    00169   // now build the eoGenOp:
    00170   // to simulate SGA (crossover with proba pCross + mutation with proba pMut
    00171   // we must construct
    00172   //     a sequential combination of
    00173   //          with proba 1, a proportional combination of
    00174   //                        a QuadCopy and our crossover
    00175   //          with proba pMut, our mutation
    00176
    00177   // but of course you're free to use any smart combination you could think of
    00178   // especially, if you have to use eoBinOp rather than eoQuad Op youùll have
    00179   // to modify that part
    00180
    00181   // First read the individual level parameters
    00182     eoValueParam<double>& pCrossParam = _parser.createParam(0.6, "pCross", "Probability of Crossover", 'C', "Variation Operators" );
    00183     // minimum check
    00184     if ( (pCrossParam.value() < 0) || (pCrossParam.value() > 1) )
    00185       throw runtime_error("Invalid pCross");
    00186
    00187     eoValueParam<double>& pMutParam = _parser.createParam(0.1, "pMut", "Probability of Mutation", 'M', "Variation Operators" );
    00188     // minimum check
    00189     if ( (pMutParam.value() < 0) || (pMutParam.value() > 1) )
    00190       throw runtime_error("Invalid pMut");
    00191
    00192
    00193   // the crossover - with probability pCross
    00194   eoProportionalOp<Indi> * propOp = new eoProportionalOp<Indi> ;
    00195   _state.storeFunctor(propOp);
    00196   eoQuadOp<Indi> *ptQuad = new eoQuadCloneOp<Indi>;
    00197   _state.storeFunctor(ptQuad);
    00198   propOp->add(*propXover, pCrossParam.value()); // crossover, with proba pcross
    00199   propOp->add(*ptQuad, 1-pCrossParam.value()); // nothing, with proba 1-pcross
    00200
    00201   // now the sequential
    00202   eoSequentialOp<Indi> *op = new eoSequentialOp<Indi>;
    00203   _state.storeFunctor(op);
    00204   op->add(*propOp, 1.0);         // always do combined crossover
    00205   op->add(*propMutation, pMutParam.value()); // then mutation, with proba pmut
    00206
    00207   // that's it - return a reference
    00208   return *op;
    00209 }
    00210 #endif