# make_op_es.h

    00001 /* (c) Maarten Keijzer, Marc Schoenauer and GeNeura Team, 2001
    00002
    00003 This library is free software; you can redistribute it and/or modify it under
    00004 the terms of the GNU Lesser General Public License as published by the Free
    00005 Software Foundation; either version 2 of the License, or (at your option) any
    00006 later version.
    00007
    00008 This library is distributed in the hope that it will be useful, but WITHOUT ANY
    00009 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
    00010 PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
    00011
    00012 You should have received a copy of the GNU Lesser General Public License along
    00013 with this library; if not, write to the Free Software Foundation, Inc., 59
    00014 Temple Place, Suite 330, Boston, MA 02111-1307 USA
    00015
    00016 Contact: http://eodev.sourceforge.net
    00017          todos@geneura.ugr.es, http://geneura.ugr.es
    00018          Marc.Schoenauer@polytechnique.fr
    00019          mkeijzer@dhi.dk
    00020  */
    00021
    00022
    00023 #ifndef EO_make_op_h
    00024 #define EO_make_op_h
    00025
    00026 // the operators
    00027 #include <eoOp.h>
    00028 #include <eoGenOp.h>
    00029 #include <eoCloneOps.h>
    00030 #include <eoOpContainer.h>
    00031 // combinations of simple eoOps (eoMonOp and eoQuadOp)
    00032 #include <eoProportionalCombinedOp.h>
    00033
    00034 // the specialized Real stuff
    00035 #include <es/eoReal.h>
    00036 #include <es/eoRealAtomXover.h>
    00037 #include <es/eoEsChromInit.h>
    00038 #include <es/eoEsMutationInit.h>
    00039 #include <es/eoEsMutate.h>
    00040 #include <es/eoEsGlobalXover.h>
    00041 #include <es/eoEsStandardXover.h>
    00042   // also need the parser and param includes
    00043 #include <utils/eoParser.h>
    00044 #include <utils/eoState.h>
    00045
    00046
    00047 /*
    00048  * This function builds the operators that will be applied to the eoReal
    00049  *
    00050  * It uses a parser (to get user parameters) and a state (to store the memory)
    00051  * the last argument is an individual, needed for 2 reasons
    00052  *     it disambiguates the call after instanciations
    00053  *     some operator might need some private information about the indis
    00054  *
    00055  * This is why the template is the complete EOT even though only the fitness
    00056  * is actually templatized here: the following only applies to bitstrings
    00057  *
    00058  * Note : the last parameter is an eoInit: if some operator needs some info
    00059  *        about the gneotypes, the init has it all (e.g. bounds, ...)
    00060  *        Simply do
    00061  *        EOT myEO;
    00062  *        _init(myEO);
    00063  *        and myEO is then an ACTUAL object
    00064 */
    00065
    00066 template <class EOT>
    00067 eoGenOp<EOT> & do_make_op(eoParser& _parser, eoState& _state, eoRealInitBounded<EOT>& _init)
    00068 {
    00069   // get std::vector size
    00070   unsigned vecSize = _init.size();
    00071
    00072   // First, decide whether the objective variables are bounded
    00073   eoValueParam<eoRealVectorBounds>& boundsParam
    00074       = _parser.getORcreateParam(eoRealVectorBounds(vecSize,eoDummyRealNoBounds),
    00075                                  "objectBounds", "Bounds for variables",
    00076                                  'B', "Variation Operators");
    00077
    00078   std::cerr << boundsParam.value() << std::endl;
    00079
    00080     // now we read Pcross and Pmut,
    00081   eoValueParam<std::string>& operatorParam
    00082       = _parser.getORcreateParam(std::string("SGA"), "operator",
    00083                                  "Description of the operator (SGA only now)",
    00084                                  'o', "Variation Operators");
    00085
    00086   if (operatorParam.value() != std::string("SGA"))
    00087     throw std::runtime_error("Sorry, only SGA-like operator available right now\n");
    00088
    00089     // now we read Pcross and Pmut,
    00090     // and create the eoGenOp that is exactly
    00091     // crossover with pcross + mutation with pmut
    00092
    00093   eoValueParam<double>& pCrossParam
    00094       = _parser.getORcreateParam(1.0, "pCross", "Probability of Crossover",
    00095                                  'C', "Variation Operators" );
    00096   // minimum check
    00097   if ( (pCrossParam.value() < 0) || (pCrossParam.value() > 1) )
    00098     throw std::runtime_error("Invalid pCross");
    00099
    00100   eoValueParam<double>& pMutParam
    00101       = _parser.getORcreateParam(1.0, "pMut", "Probability of Mutation",
    00102                                  'M', "Variation Operators" );
    00103   // minimum check
    00104   if ( (pMutParam.value() < 0) || (pMutParam.value() > 1) )
    00105     throw std::runtime_error("Invalid pMut");
    00106
    00107
    00108   // crossover
    00110   // ES crossover
    00111   eoValueParam<std::string>& crossTypeParam
    00112       = _parser.getORcreateParam(std::string("global"), "crossType",
    00113                                  "Type of ES recombination (global or standard)",
    00114                                  'C', "Variation Operators");
    00115
    00116   eoValueParam<std::string>& crossObjParam
    00117       = _parser.getORcreateParam(std::string("discrete"), "crossObj",
    00118                                  "Recombination of object variables (discrete, intermediate or none)",
    00119                                  'O', "Variation Operators");
    00120   eoValueParam<std::string>& crossStdevParam
    00121       = _parser.getORcreateParam(std::string("intermediate"), "crossStdev",
    00122                                  "Recombination of mutation strategy parameters "
    00123                                  "(intermediate, discrete or none)",
    00124                                  'S', "Variation Operators");
    00125
    00126   // The pointers: first the atom Xover
    00127   eoBinOp<double> *ptObjAtomCross = NULL;
    00128   eoBinOp<double> *ptStdevAtomCross = NULL;
    00129   // then the EOT-level one (need to be an eoGenOp as global Xover is
    00130   eoGenOp<EOT> *ptCross;
    00131
    00132   // check for the atom Xovers
    00133   if (crossObjParam.value() == std::string("discrete"))
    00134     ptObjAtomCross = new eoDoubleExchange;
    00135   else if (crossObjParam.value() == std::string("intermediate"))
    00136     ptObjAtomCross = new eoDoubleIntermediate;
    00137   else if (crossObjParam.value() == std::string("none"))
    00138     ptObjAtomCross = new eoBinCloneOp<double>;
    00139   else throw std::runtime_error("Invalid Object variable crossover type");
    00140
    00141   if (crossStdevParam.value() == std::string("discrete"))
    00142     ptStdevAtomCross = new eoDoubleExchange;
    00143   else if (crossStdevParam.value() == std::string("intermediate"))
    00144     ptStdevAtomCross = new eoDoubleIntermediate;
    00145   else if (crossStdevParam.value() == std::string("none"))
    00146     ptStdevAtomCross = new eoBinCloneOp<double>;
    00147   else throw std::runtime_error("Invalid mutation strategy parameter crossover type");
    00148
    00149   // and build the indi Xover
    00150   if (crossTypeParam.value() == std::string("global"))
    00151     ptCross = new eoEsGlobalXover<EOT>(*ptObjAtomCross, *ptStdevAtomCross);
    00152   else if (crossTypeParam.value() == std::string("standard"))
    00153     {      // using a standard eoBinOp, but wrap it into an eoGenOp
    00154       eoBinOp<EOT> & crossTmp = _state.storeFunctor(
    00155              new eoEsStandardXover<EOT>(*ptObjAtomCross, *ptStdevAtomCross)
    00156              );
    00157       ptCross = new eoBinGenOp<EOT>(crossTmp);
    00158     }
    00159   else throw std::runtime_error("Invalide Object variable crossover type");
    00160
    00161   // now that everything is OK, DON'T FORGET TO STORE MEMORY
    00162   _state.storeFunctor(ptObjAtomCross);
    00163   _state.storeFunctor(ptStdevAtomCross);
    00164   _state.storeFunctor(ptCross);
    00165
    00166   //  mutation
    00168
    00169   // Ok, time to set up the self-adaptive mutation
    00170   // Proxy for the mutation parameters
    00171   eoEsMutationInit mutateInit(_parser, "Variation Operators");
    00172
    00173   eoEsMutate<EOT> & mut =  _state.storeFunctor(
    00174       new eoEsMutate<EOT>(mutateInit, boundsParam.value()));
    00175
    00176   // now the general op - a sequential application of crossover and mutatation
    00177   // no need to first have crossover combined with a clone as it is an
    00178   // eoBinOp and not an eoQuadOp as in SGA paradigm
    00179
    00180   eoSequentialOp<EOT> & op = _state.storeFunctor(new eoSequentialOp<EOT>);
    00181   op.add(*ptCross, pCrossParam.value());
    00182   op.add(mut, pMutParam.value());
    00183
    00184   // that's it!
    00185   return op;
    00186 }
    00187 #endif // EO_make_op_h
    00188
    00189
    00190
    00191 // Local Variables:
    00192 // coding: iso-8859-1
    00193 // mode:C++
    00194 // c-file-style: "Stroustrup"
    00195 // comment-column: 35
    00196 // fill-column: 80
    00197 // End: