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:

Generated on Thu Oct 19 05:06:41 2006 for EO by  doxygen 1.3.9.1