EvolvingObjects
make_op.h
00001 // -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
00002 
00003 //-----------------------------------------------------------------------------
00004 // make_op.h
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 GA stuff
00039 #include <ga/eoBit.h>
00040 #include <ga/eoBitOp.h>
00041   // also need the parser and param includes
00042 #include <utils/eoParser.h>
00043 #include <utils/eoState.h>
00044 
00045 
00047 // canonical (crossover + mutation) only at the moment //
00048 
00049 /*
00050  * This function builds the operators that will be applied to the bitstrings
00051  *
00052  * It uses a parser (to get user parameters) and a state (to store the memory)
00053  * the last argument is an individual, needed for 2 reasons
00054  *     it disambiguates the call after instanciations
00055  *     some operator might need some private information about the indis
00056  *
00057  * This is why the template is the complete EOT even though only the fitness
00058  * is actually templatized here: the following only applies to bitstrings
00059  *
00060  * Note : the last parameter is an eoInit: if some operator needs some info
00061  *        about the gneotypes, the init has it all (e.g. bounds, ...)
00062  *        Simply do
00063  *        EOT myEO;
00064  *        _init(myEO);
00065  *        and myEO is then an ACTUAL object
00066  *
00067  * @ingroup bitstring
00068  * @ingroup Builders
00069 */
00070 
00071 template <class EOT>
00072 eoGenOp<EOT> & do_make_op(eoParser& _parser, eoState& _state, eoInit<EOT>& _init)
00073 {
00074   // this is a temporary version, while Maarten codes the full tree-structured
00075   // general operator input
00076   // BTW we must leave that simple version available somehow, as it is the one
00077   // that 90% people use!
00078     eoValueParam<std::string>& operatorParam =  _parser.createParam(std::string("SGA"), "operator", "Description of the operator (SGA only now)", 'o', "Variation Operators");
00079 
00080     if (operatorParam.value() != std::string("SGA"))
00081         throw std::runtime_error("Only SGA-like operator available right now\n");
00082 
00083     // now we read Pcross and Pmut,
00084     // the relative weights for all crossovers -> proportional choice
00085     // the relative weights for all mutations -> proportional choice
00086     // and create the eoGenOp that is exactly
00087     // crossover with pcross + mutation with pmut
00088 
00089     eoValueParam<double>& pCrossParam = _parser.createParam(0.6, "pCross", "Probability of Crossover", 'C', "Variation Operators" );
00090     // minimum check
00091     if ( (pCrossParam.value() < 0) || (pCrossParam.value() > 1) )
00092       throw std::runtime_error("Invalid pCross");
00093 
00094     eoValueParam<double>& pMutParam = _parser.createParam(0.1, "pMut", "Probability of Mutation", 'M', "Variation Operators" );
00095     // minimum check
00096     if ( (pMutParam.value() < 0) || (pMutParam.value() > 1) )
00097       throw std::runtime_error("Invalid pMut");
00098 
00099     // the crossovers
00101     // the parameters
00102     eoValueParam<double>& onePointRateParam = _parser.createParam(double(1.0), "onePointRate", "Relative rate for one point crossover", '1', "Variation Operators" );
00103     // minimum check
00104     if ( (onePointRateParam.value() < 0) )
00105       throw std::runtime_error("Invalid onePointRate");
00106 
00107     eoValueParam<double>& twoPointsRateParam = _parser.createParam(double(1.0), "twoPointRate", "Relative rate for two point crossover", '2', "Variation Operators" );
00108     // minimum check
00109     if ( (twoPointsRateParam.value() < 0) )
00110       throw std::runtime_error("Invalid twoPointsRate");
00111 
00112     eoValueParam<double>& uRateParam = _parser.createParam(double(2.0), "uRate", "Relative rate for uniform crossover", 'U', "Variation Operators" );
00113     // minimum check
00114     if ( (uRateParam.value() < 0) )
00115       throw std::runtime_error("Invalid uRate");
00116 
00117     // minimum check
00118     // bool bCross = true; // not used ?
00119     if (onePointRateParam.value()+twoPointsRateParam.value()+uRateParam.value()==0)
00120       {
00121         std::cerr << "Warning: no crossover" << std::endl;
00122         // bCross = false;
00123       }
00124 
00125     // Create the CombinedQuadOp
00126     eoPropCombinedQuadOp<EOT> *ptCombinedQuadOp = NULL;
00127     eoQuadOp<EOT> *ptQuad = NULL;
00128     // 1-point crossover for bitstring
00129     ptQuad = new eo1PtBitXover<EOT>;
00130     _state.storeFunctor(ptQuad);
00131     ptCombinedQuadOp = new eoPropCombinedQuadOp<EOT>(*ptQuad, onePointRateParam.value());
00132 
00133     // uniform crossover for bitstring
00134     ptQuad = new eoUBitXover<EOT>;
00135     _state.storeFunctor(ptQuad);
00136     ptCombinedQuadOp->add(*ptQuad, uRateParam.value());
00137 
00138     // 2-points xover
00139     ptQuad = new eoNPtsBitXover<EOT>;
00140     _state.storeFunctor(ptQuad);
00141     ptCombinedQuadOp->add(*ptQuad, twoPointsRateParam.value());
00142 
00143     // don't forget to store the CombinedQuadOp
00144     _state.storeFunctor(ptCombinedQuadOp);
00145 
00146     // the mutations
00148     // the parameters
00149     eoValueParam<double> & pMutPerBitParam = _parser.createParam(0.01, "pMutPerBit", "Probability of flipping 1 bit in bit-flip mutation", 'b', "Variation Operators" );
00150     // minimum check
00151     if ( (pMutPerBitParam.value() < 0) || (pMutPerBitParam.value() > 0.5) )
00152       throw std::runtime_error("Invalid pMutPerBit");
00153 
00154     eoValueParam<double> & bitFlipRateParam = _parser.createParam(0.01, "bitFlipRate", "Relative rate for bit-flip mutation", 's', "Variation Operators" );
00155     // minimum check
00156     if ( (bitFlipRateParam.value() < 0) )
00157       throw std::runtime_error("Invalid bitFlipRate");
00158 
00159     // oneBitFlip
00160     eoValueParam<double> & oneBitRateParam = _parser.createParam(0.01, "oneBitRate", "Relative rate for deterministic bit-flip mutation", 'd', "Variation Operators" );
00161     // minimum check
00162     if ( (oneBitRateParam.value() < 0) )
00163       throw std::runtime_error("Invalid oneBitRate");
00164 
00165     // kBitFlip
00166     eoValueParam<unsigned> & kBitParam = _parser.createParam((unsigned)1, "kBit", "Number of bit for deterministic k bit-flip mutation", 0, "Variation Operators" );
00167     // minimum check
00168     if ( ! kBitParam.value() )
00169       throw std::runtime_error("Invalid kBit");
00170 
00171     eoValueParam<double> & kBitRateParam = _parser.createParam(0.0, "kBitRate", "Relative rate for deterministic k bit-flip mutation", 0, "Variation Operators" );
00172     // minimum check
00173     if ( (kBitRateParam.value() < 0) )
00174       throw std::runtime_error("Invalid kBitRate");
00175 
00176     // minimum check
00177     // bool bMut = true; // not used ?
00178     if (bitFlipRateParam.value()+oneBitRateParam.value()==0)
00179       {
00180         std::cerr << "Warning: no mutation" << std::endl;
00181         // bMut = false;
00182       }
00183 
00184     // Create the CombinedMonOp
00185     eoPropCombinedMonOp<EOT> *ptCombinedMonOp = NULL;
00186     eoMonOp<EOT> *ptMon = NULL;
00187 
00188   // standard bit-flip mutation for bitstring
00189   ptMon = new eoBitMutation<EOT>(pMutPerBitParam.value());
00190   _state.storeFunctor(ptMon);
00191   // create the CombinedMonOp
00192   ptCombinedMonOp = new eoPropCombinedMonOp<EOT>(*ptMon, bitFlipRateParam.value());
00193 
00194   // mutate exactly 1 bit per individual
00195   ptMon = new eoDetBitFlip<EOT>;
00196   _state.storeFunctor(ptMon);
00197   ptCombinedMonOp->add(*ptMon, oneBitRateParam.value());
00198 
00199   // mutate exactly k bit per individual
00200   ptMon = new eoDetBitFlip<EOT>(kBitParam.value());
00201   _state.storeFunctor(ptMon);
00202   ptCombinedMonOp->add(*ptMon, kBitRateParam.value());
00203 
00204   _state.storeFunctor(ptCombinedMonOp);
00205 
00206   // now build the eoGenOp:
00207   // to simulate SGA (crossover with proba pCross + mutation with proba pMut
00208   // we must construct
00209   //     a sequential combination of
00210   //          with proba 1, a proportional combination of
00211   //                        a QuadCopy and our crossover
00212   //          with proba pMut, our mutation
00213 
00214   // the crossover - with probability pCross
00215   eoProportionalOp<EOT> * cross = new eoProportionalOp<EOT> ;
00216   _state.storeFunctor(cross);
00217   ptQuad = new eoQuadCloneOp<EOT>;
00218   _state.storeFunctor(ptQuad);
00219   cross->add(*ptCombinedQuadOp, pCrossParam.value()); // user crossover
00220   cross->add(*ptQuad, 1-pCrossParam.value()); // clone operator
00221 
00222   // now the sequential
00223   eoSequentialOp<EOT> *op = new eoSequentialOp<EOT>;
00224   _state.storeFunctor(op);
00225   op->add(*cross, 1.0);  // always crossover (but clone with prob 1-pCross
00226   op->add(*ptCombinedMonOp, pMutParam.value());
00227 
00228   // that's it!
00229   return *op;
00230 }
00231 #endif
 All Classes Namespaces Files Functions Variables Typedefs Friends