make_op_real.h

00001 // -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
00002 
00003 //-----------------------------------------------------------------------------
00004 // make_op.h - the real-valued version
00005 // (c) Maarten Keijzer, Marc Schoenauer 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_h
00028 #define _make_op_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 
00038 // the specialized Real stuff
00039 #include <es/eoReal.h>
00040 #include <es/eoEsChromInit.h>
00041 #include <es/eoRealOp.h>
00042 #include <es/eoNormalMutation.h>
00043   // also need the parser and param includes
00044 #include <utils/eoParser.h>
00045 #include <utils/eoState.h>
00046 
00047 
00048 /*
00049  * This function builds the operators that will be applied to the eoReal
00050  *
00051  * It uses a parser (to get user parameters) and a state (to store the memory)
00052  * the last argument is an individual, needed for 2 reasons
00053  *     it disambiguates the call after instanciations
00054  *     some operator might need some private information about the indis
00055  *
00056  * This is why the template is the complete EOT even though only the fitness
00057  * is actually templatized here: the following only applies to bitstrings
00058  *
00059  * Note : the last parameter is an eoInit: if some operator needs some info
00060  *        about the gneotypes, the init has it all (e.g. bounds, ...)
00061  *        Simply do
00062  *        EOT myEO;
00063  *        _init(myEO);
00064  *        and myEO is then an ACTUAL object
00065 */
00066 
00067 template <class EOT>
00068 eoGenOp<EOT> & do_make_op(eoParser& _parser, eoState& _state, eoRealInitBounded<EOT>& _init)
00069 {
00070   // get std::vector size
00071   unsigned vecSize = _init.size();
00072 
00073   // First, decide whether the objective variables are bounded
00074   eoValueParam<eoRealVectorBounds>& boundsParam
00075       = _parser.getORcreateParam(eoRealVectorBounds(vecSize,eoDummyRealNoBounds), "objectBounds",
00076                                  "Bounds for variables", 'B', "Variation Operators");
00077 
00078   // this is a temporary version(!),
00079   // while Maarten codes the full tree-structured general operator input
00080   // BTW we must leave that simple version available somehow, as it is the one
00081   // that 90% people use!
00082   eoValueParam<std::string>& operatorParam
00083       = _parser.getORcreateParam(std::string("SGA"), "operator",
00084                                  "Description of the operator (SGA only now)",
00085                                  'o', "Variation Operators");
00086 
00087   if (operatorParam.value() != std::string("SGA"))
00088     throw std::runtime_error("Sorry, only SGA-like operator available right now\n");
00089 
00090     // now we read Pcross and Pmut,
00091     // the relative weights for all crossovers -> proportional choice
00092     // the relative weights for all mutations -> proportional choice
00093     // and create the eoGenOp that is exactly
00094     // crossover with pcross + mutation with pmut
00095 
00096   eoValueParam<double>& pCrossParam
00097       = _parser.getORcreateParam(0.6, "pCross",
00098                                  "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(0.1, "pMut",
00106                                  "Probability of Mutation",
00107                                  'M', "Variation Operators" );
00108   // minimum check
00109   if ( (pMutParam.value() < 0) || (pMutParam.value() > 1) )
00110     throw std::runtime_error("Invalid pMut");
00111 
00112     // the crossovers
00114     // the parameters
00115   eoValueParam<double>& alphaParam
00116       = _parser.getORcreateParam(double(0.0), "alpha",
00117                                  "Bound for factor of linear recombinations",
00118                                  'a', "Variation Operators" );
00119   // minimum check
00120   if ( (alphaParam.value() < 0) )
00121     throw std::runtime_error("Invalid BLX coefficient alpha");
00122 
00123 
00124   eoValueParam<double>& segmentRateParam
00125       = _parser.getORcreateParam(double(1.0), "segmentRate",
00126                                  "Relative rate for segment crossover",
00127                                  's', "Variation Operators" );
00128   // minimum check
00129   if ( (segmentRateParam.value() < 0) )
00130     throw std::runtime_error("Invalid segmentRate");
00131 
00132   eoValueParam<double>& hypercubeRateParam
00133       = _parser.getORcreateParam(double(1.0), "hypercubeRate",
00134                                  "Relative rate for hypercube crossover",
00135                                  'A', "Variation Operators" );
00136   // minimum check
00137   if ( (hypercubeRateParam.value() < 0) )
00138     throw std::runtime_error("Invalid hypercubeRate");
00139 
00140   eoValueParam<double>& uxoverRateParam
00141       = _parser.getORcreateParam(double(1.0), "uxoverRate",
00142                                  "Relative rate for uniform crossover",
00143                                  'A', "Variation Operators" );
00144   // minimum check
00145   if ( (uxoverRateParam.value() < 0) )
00146     throw std::runtime_error("Invalid uxoverRate");
00147 
00148     // minimum check
00149   bool bCross = true;
00150   if (segmentRateParam.value()+hypercubeRateParam.value()+uxoverRateParam.value()==0)
00151     {
00152       std::cerr << "Warning: no crossover" << std::endl;
00153       bCross = false;
00154     }
00155 
00156   // Create the CombinedQuadOp
00157   eoPropCombinedQuadOp<EOT> *ptCombinedQuadOp = NULL;
00158   eoQuadOp<EOT> *ptQuad = NULL;
00159 
00160   if (bCross)
00161     {
00162       // segment crossover for bitstring - pass it the bounds
00163       ptQuad = new eoSegmentCrossover<EOT>(boundsParam.value(), alphaParam.value());
00164       _state.storeFunctor(ptQuad);
00165       ptCombinedQuadOp = new eoPropCombinedQuadOp<EOT>(*ptQuad, segmentRateParam.value());
00166 
00167         // hypercube crossover
00168       ptQuad = new eoHypercubeCrossover<EOT>(boundsParam.value(), alphaParam.value());
00169       _state.storeFunctor(ptQuad);
00170       ptCombinedQuadOp->add(*ptQuad, hypercubeRateParam.value());
00171 
00172         // uniform crossover
00173       ptQuad = new eoRealUXover<EOT>();
00174       _state.storeFunctor(ptQuad);
00175       ptCombinedQuadOp->add(*ptQuad, uxoverRateParam.value());
00176 
00177       // don't forget to store the CombinedQuadOp
00178       _state.storeFunctor(ptCombinedQuadOp);
00179     }
00180 
00181   // the mutations
00183   // the parameters
00184   eoValueParam<double> & epsilonParam
00185       = _parser.getORcreateParam(0.01, "epsilon",
00186                                  "Half-size of interval for Uniform Mutation",
00187                                  'e', "Variation Operators" );
00188   // minimum check
00189   if ( (epsilonParam.value() < 0) )
00190     throw std::runtime_error("Invalid epsilon");
00191 
00192   eoValueParam<double> & uniformMutRateParam
00193       = _parser.getORcreateParam(1.0, "uniformMutRate",
00194                                  "Relative rate for uniform mutation",
00195                                  'u', "Variation Operators" );
00196   // minimum check
00197   if ( (uniformMutRateParam.value() < 0) )
00198     throw std::runtime_error("Invalid uniformMutRate");
00199 
00200   eoValueParam<double> & detMutRateParam
00201       = _parser.getORcreateParam(1.0, "detMutRate",
00202                                  "Relative rate for deterministic uniform mutation",
00203                                  'd', "Variation Operators" );
00204   // minimum check
00205   if ( (detMutRateParam.value() < 0) )
00206     throw std::runtime_error("Invalid detMutRate");
00207 
00208   eoValueParam<double> & normalMutRateParam
00209       = _parser.getORcreateParam(1.0, "normalMutRate",
00210                                  "Relative rate for Gaussian mutation", 'd', "Variation Operators" );
00211   // minimum check
00212   if ( (normalMutRateParam.value() < 0) )
00213     throw std::runtime_error("Invalid normalMutRate");
00214 
00215   eoValueParam<double> & sigmaParam
00216       = _parser.getORcreateParam(0.3, "sigma",
00217                                  "Sigma (fixed) for Gaussian mutation",
00218                                  's', "Variation Operators" );
00219 
00220   eoValueParam<double> & pNormalParam
00221       = _parser.getORcreateParam(1.0, "pNormal",
00222                                  "Proba. to change each variable for Gaussian mutation",
00223                                  's', "Variation Operators" );
00224 
00225     // minimum check
00226   bool bMut = true;
00227   if (uniformMutRateParam.value()+detMutRateParam.value()+normalMutRateParam.value()==0)
00228     {
00229       std::cerr << "Warning: no mutation" << std::endl;
00230       bMut = false;
00231     }
00232   if (!bCross && !bMut)
00233     throw std::runtime_error("No operator called in SGA operator definition!!!");
00234 
00235     // Create the CombinedMonOp
00236   eoPropCombinedMonOp<EOT> *ptCombinedMonOp = NULL;
00237   eoMonOp<EOT> *ptMon = NULL;
00238 
00239   if (bMut)
00240     {
00241       // uniform mutation on all components:
00242       // offspring(i) uniformly chosen in [parent(i)-epsilon, parent(i)+epsilon]
00243       ptMon = new eoUniformMutation<EOT>(boundsParam.value(), epsilonParam.value());
00244       _state.storeFunctor(ptMon);
00245       // create the CombinedMonOp
00246       ptCombinedMonOp = new eoPropCombinedMonOp<EOT>(*ptMon, uniformMutRateParam.value());
00247 
00248         // mutate exactly 1 component (uniformly) per individual
00249       ptMon = new eoDetUniformMutation<EOT>(boundsParam.value(), epsilonParam.value());
00250       _state.storeFunctor(ptMon);
00251       ptCombinedMonOp->add(*ptMon, detMutRateParam.value());
00252 
00253       // mutate all component using Gaussian mutation
00254       ptMon = new eoNormalVecMutation<EOT>(boundsParam.value(), sigmaParam.value(), pNormalParam.value());
00255       _state.storeFunctor(ptMon);
00256       ptCombinedMonOp->add(*ptMon, normalMutRateParam.value());
00257       _state.storeFunctor(ptCombinedMonOp);
00258     }
00259 
00260   // now build the eoGenOp:
00261   // to simulate SGA (crossover with proba pCross + mutation with proba pMut
00262   // we must construct
00263   //     a sequential combination of
00264   //          with proba 1, a proportional combination of
00265   //                        a QuadCopy and our crossover
00266   //          with proba pMut, our mutation
00267 
00268   // the crossover - with probability pCross
00269   eoProportionalOp<EOT> * cross = new eoProportionalOp<EOT> ;
00270   _state.storeFunctor(cross);
00271   ptQuad = new eoQuadCloneOp<EOT>;
00272   _state.storeFunctor(ptQuad);
00273   cross->add(*ptCombinedQuadOp, pCrossParam.value()); // user crossover
00274   cross->add(*ptQuad, 1-pCrossParam.value()); // clone operator
00275 
00276   // now the sequential
00277   eoSequentialOp<EOT> & op =  _state.storeFunctor(new eoSequentialOp<EOT>);
00278   op.add(*cross, 1.0);   // always crossover (but clone with prob 1-pCross
00279   op.add(*ptCombinedMonOp, pMutParam.value());
00280 
00281   // that's it!
00282   return op;
00283 }
00284 #endif

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