EvolvingObjects
|
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: