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