EvolvingObjects
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 
00051 /*
00052  * This function builds the operators that will be applied to the eoReal
00053  *
00054  * It uses a parser (to get user parameters) and a state (to store the memory)
00055  * the last argument is an individual, needed for 2 reasons
00056  *     it disambiguates the call after instanciations
00057  *     some operator might need some private information about the indis
00058  *
00059  * This is why the template is the complete EOT even though only the fitness
00060  * is actually templatized here: the following only applies to bitstrings
00061  *
00062  * Note : the last parameter is an eoInit: if some operator needs some info
00063  *        about the gneotypes, the init has it all (e.g. bounds, ...)
00064  *        Simply do
00065  *        EOT myEO;
00066  *        _init(myEO);
00067  *        and myEO is then an ACTUAL object
00068 */
00069 
00070 template <class EOT>
00071 eoGenOp<EOT> & do_make_op(eoParser& _parser, eoState& _state, eoRealInitBounded<EOT>& _init)
00072 {
00073   // get std::vector size
00074   unsigned vecSize = _init.size();
00075 
00076   // First, decide whether the objective variables are bounded
00077   eoValueParam<eoRealVectorBounds>& boundsParam
00078       = _parser.getORcreateParam(eoRealVectorBounds(vecSize,eoDummyRealNoBounds),
00079                                  "objectBounds", "Bounds for variables",
00080                                  'B', "Variation Operators");
00081 
00082   std::cerr << boundsParam.value() << std::endl;
00083 
00084     // now we read Pcross and Pmut,
00085   eoValueParam<std::string>& operatorParam
00086       = _parser.getORcreateParam(std::string("SGA"), "operator",
00087                                  "Description of the operator (SGA only now)",
00088                                  'o', "Variation Operators");
00089 
00090   if (operatorParam.value() != std::string("SGA"))
00091     throw std::runtime_error("Sorry, only SGA-like operator available right now\n");
00092 
00093     // now we read Pcross and Pmut,
00094     // and create the eoGenOp that is exactly
00095     // crossover with pcross + mutation with pmut
00096 
00097   eoValueParam<double>& pCrossParam
00098       = _parser.getORcreateParam(1.0, "pCross", "Probability of Crossover",
00099                                  'C', "Variation Operators" );
00100   // minimum check
00101   if ( (pCrossParam.value() < 0) || (pCrossParam.value() > 1) )
00102     throw std::runtime_error("Invalid pCross");
00103 
00104   eoValueParam<double>& pMutParam
00105       = _parser.getORcreateParam(1.0, "pMut", "Probability of Mutation",
00106                                  'M', "Variation Operators" );
00107   // minimum check
00108   if ( (pMutParam.value() < 0) || (pMutParam.value() > 1) )
00109     throw std::runtime_error("Invalid pMut");
00110 
00111 
00112   // crossover
00114   // ES crossover
00115   eoValueParam<std::string>& crossTypeParam
00116       = _parser.getORcreateParam(std::string("global"), "crossType",
00117                                  "Type of ES recombination (global or standard)",
00118                                  'C', "Variation Operators");
00119 
00120   eoValueParam<std::string>& crossObjParam
00121       = _parser.getORcreateParam(std::string("discrete"), "crossObj",
00122                                  "Recombination of object variables (discrete, intermediate or none)",
00123                                  'O', "Variation Operators");
00124   eoValueParam<std::string>& crossStdevParam
00125       = _parser.getORcreateParam(std::string("intermediate"), "crossStdev",
00126                                  "Recombination of mutation strategy parameters "
00127                                  "(intermediate, discrete or none)",
00128                                  'S', "Variation Operators");
00129 
00130   // The pointers: first the atom Xover
00131   eoBinOp<double> *ptObjAtomCross = NULL;
00132   eoBinOp<double> *ptStdevAtomCross = NULL;
00133   // then the EOT-level one (need to be an eoGenOp as global Xover is
00134   eoGenOp<EOT> *ptCross;
00135 
00136   // check for the atom Xovers
00137   if (crossObjParam.value() == std::string("discrete"))
00138     ptObjAtomCross = new eoDoubleExchange;
00139   else if (crossObjParam.value() == std::string("intermediate"))
00140     ptObjAtomCross = new eoDoubleIntermediate;
00141   else if (crossObjParam.value() == std::string("none"))
00142     ptObjAtomCross = new eoBinCloneOp<double>;
00143   else throw std::runtime_error("Invalid Object variable crossover type");
00144 
00145   if (crossStdevParam.value() == std::string("discrete"))
00146     ptStdevAtomCross = new eoDoubleExchange;
00147   else if (crossStdevParam.value() == std::string("intermediate"))
00148     ptStdevAtomCross = new eoDoubleIntermediate;
00149   else if (crossStdevParam.value() == std::string("none"))
00150     ptStdevAtomCross = new eoBinCloneOp<double>;
00151   else throw std::runtime_error("Invalid mutation strategy parameter crossover type");
00152 
00153   // and build the indi Xover
00154   if (crossTypeParam.value() == std::string("global"))
00155     ptCross = new eoEsGlobalXover<EOT>(*ptObjAtomCross, *ptStdevAtomCross);
00156   else if (crossTypeParam.value() == std::string("standard"))
00157     {      // using a standard eoBinOp, but wrap it into an eoGenOp
00158       eoBinOp<EOT> & crossTmp = _state.storeFunctor(
00159              new eoEsStandardXover<EOT>(*ptObjAtomCross, *ptStdevAtomCross)
00160              );
00161       ptCross = new eoBinGenOp<EOT>(crossTmp);
00162     }
00163   else throw std::runtime_error("Invalide Object variable crossover type");
00164 
00165   // now that everything is OK, DON'T FORGET TO STORE MEMORY
00166   _state.storeFunctor(ptObjAtomCross);
00167   _state.storeFunctor(ptStdevAtomCross);
00168   _state.storeFunctor(ptCross);
00169 
00170   //  mutation
00172 
00173   // Ok, time to set up the self-adaptive mutation
00174   // Proxy for the mutation parameters
00175   eoEsMutationInit mutateInit(_parser, "Variation Operators");
00176 
00177   eoEsMutate<EOT> & mut =  _state.storeFunctor(
00178       new eoEsMutate<EOT>(mutateInit, boundsParam.value()));
00179 
00180   // now the general op - a sequential application of crossover and mutatation
00181   // no need to first have crossover combined with a clone as it is an
00182   // eoBinOp and not an eoQuadOp as in SGA paradigm
00183 
00184   eoSequentialOp<EOT> & op = _state.storeFunctor(new eoSequentialOp<EOT>);
00185   op.add(*ptCross, pCrossParam.value());
00186   op.add(mut, pMutParam.value());
00187 
00188   // that's it!
00189   return op;
00190 }
00191 #endif // EO_make_op_h
00192 
00193 
00196 // Local Variables:
00197 // coding: iso-8859-1
00198 // mode:C++
00199 // c-file-style: "Stroustrup"
00200 // comment-column: 35
00201 // fill-column: 80
00202 // End:
 All Classes Namespaces Files Functions Variables Typedefs Friends