# eoParseTreeOp.h

    00001 // -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
    00002
    00003 //-----------------------------------------------------------------------------
    00004 // eoParseTreeOp.h : crossover and mutation operator for  the eoParseTree class
    00005 // (c) Maarten Keijzer 2000  for eoSubtreeXOver, eoBranchMutation
    00006 // (c) Jeroen Eggermont 2001 for other mutation operators
    00007
    00008 /*
    00009     This library is free software; you can redistribute it and/or
    00010     modify it under the terms of the GNU Lesser General Public
    00011     License as published by the Free Software Foundation; either
    00012     version 2 of the License, or (at your option) any later version.
    00013
    00014     This library is distributed in the hope that it will be useful,
    00015     but WITHOUT ANY WARRANTY; without even the implied warranty of
    00016     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00017     Lesser General Public License for more details.
    00018
    00019     You should have received a copy of the GNU Lesser General Public
    00020     License along with this library; if not, write to the Free Software
    00021     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    00022
    00023     Contact: todos@geneura.ugr.es, http://geneura.ugr.es
    00024              mak@dhi.dk
    00025              jeggermo@liacs.nl
    00026  */
    00027 //-----------------------------------------------------------------------------
    00028
    00029 #ifndef eoParseTreeOp_h
    00030 #define eoParseTreeOp_h
    00031
    00032 #include <EO.h>
    00033 #include <eoOp.h>
    00034
    00035 #include <gp/eoParseTree.h>
    00036
    00041 template<class FType, class Node>
    00042 class eoSubtreeXOver: public eoQuadOp< eoParseTree<FType, Node> > {
    00043 public:
    00044
    00045   typedef eoParseTree<FType,Node> EoType;
    00050   eoSubtreeXOver( unsigned _max_length)
    00051     : eoQuadOp<EoType>(), max_length(_max_length) {};
    00052
    00054   virtual std::string className() const { return "eoSubtreeXOver"; };
    00055
    00057   virtual ~eoSubtreeXOver () {};
    00058
    00064   bool operator()(EoType & _eo1, EoType & _eo2 )
    00065   {
    00066           int i = rng.random(_eo1.size());
    00067           int j = rng.random(_eo2.size());
    00068
    00069           typename parse_tree<Node>::subtree tmp = _eo1[i];
    00070           _eo1[i] = _eo2[j]; // insert subtree
    00071           _eo2[j] = tmp;
    00072
    00073           _eo1.pruneTree(max_length);
    00074           _eo2.pruneTree(max_length);
    00075
    00076     return true;
    00077   }
    00078  private:
    00079   unsigned max_length;
    00080 };
    00081
    00086 template<class FType, class Node>
    00087 class eoBranchMutation: public eoMonOp< eoParseTree<FType, Node> >
    00088 {
    00089 public:
    00090
    00091   typedef eoParseTree<FType,Node> EoType;
    00097   eoBranchMutation(eoInit<EoType>& _init, unsigned _max_length)
    00098     : eoMonOp<EoType>(), max_length(_max_length), initializer(_init)
    00099   {};
    00100
    00102   virtual std::string className() const { return "eoBranchMutation"; };
    00103
    00105   virtual ~eoBranchMutation() {};
    00106
    00111   bool operator()(EoType& _eo1 )
    00112   {
    00113           int i = rng.random(_eo1.size());
    00114
    00115       EoType eo2;
    00116       initializer(eo2);
    00117
    00118           int j = rng.random(eo2.size());
    00119
    00120           _eo1[i] = eo2[j]; // insert subtree
    00121
    00122           _eo1.pruneTree(max_length);
    00123
    00124     return true;
    00125   }
    00126
    00127 private :
    00128
    00129   unsigned max_length;
    00130   eoInit<EoType>& initializer;
    00131 };
    00132
    00133 // Additional Mutation operators from
    00134 // TITLE:"Genetic Programming~An Introduction"
    00135 // AUTHORS: Banzhaf, Nordin, Keller, Francone
    00136 // ISBN: 3-920993-58-6
    00137 // ISBN: 1-55860-510-X
    00138 //
    00139 // For the eoParseTree class
    00140
    00146 template<class FType, class Node>
    00147 class eoPointMutation: public eoMonOp< eoParseTree<FType, Node> >
    00148 {
    00149 public:
    00150
    00151   typedef eoParseTree<FType,Node> EoType;
    00152
    00157   eoPointMutation( std::vector<Node>& _initializor)
    00158     : eoMonOp<EoType>(), initializor(_initializor)
    00159   {};
    00160
    00162   virtual std::string className() const { return "eoPointMutation"; };
    00163
    00165   virtual ~eoPointMutation() {};
    00166
    00171   bool operator()(EoType& _eo1 )
    00172   {
    00173         // select a random node i that is to be mutated
    00174         int i = rng.random(_eo1.size());
    00175         // request the arity of the node that is to be replaced
    00176         int arity = _eo1[i].arity();
    00177
    00178         int j=0;
    00179
    00180         do
    00181         {
    00182                 j = rng.random(initializor.size());
    00183
    00184         }while ((initializor[j].arity() != arity));
    00185
    00186         _eo1[i] = initializor[j];
    00187
    00188
    00189
    00190         return true;
    00191   }
    00192
    00193 private :
    00194         std::vector<Node>& initializor;
    00195
    00196 };
    00197
    00203 template<class FType, class Node>
    00204 class eoExpansionMutation: public eoMonOp< eoParseTree<FType, Node> >
    00205 {
    00206 public:
    00207
    00208   typedef eoParseTree<FType, Node> EoType;
    00209
    00215   eoExpansionMutation(eoInit<EoType>& _init, unsigned _max_length)
    00216     : eoMonOp<EoType>(), max_length(_max_length), initializer(_init)
    00217   {};
    00218
    00220   virtual std::string className() const { return "eoExpansionMutation"; };
    00221
    00223   virtual ~eoExpansionMutation() {};
    00228   bool operator()(EoType& _eo1 )
    00229   {
    00230           int i = rng.random(_eo1.size());
    00231           // look for a terminal
    00232           while (_eo1[i].arity() != 0)
    00233           {
    00234                 i= rng.random(_eo1.size());
    00235           };
    00236
    00237           // create a new tree to
    00238           EoType eo2;
    00239           // make sure we get a tree with more than just a terminal
    00240           do
    00241           {
    00242                 initializer(eo2);
    00243           }while(eo2.size() == 1);
    00244
    00245           int j = rng.random(eo2.size());
    00246           // make sure we select a subtree (and not a terminal)
    00247           while((eo2[j].arity() == 0))
    00248           {
    00249                 j = rng.random(eo2.size());
    00250           };
    00251
    00252
    00253           _eo1[i] = eo2[j]; // insert subtree
    00254
    00255           _eo1.pruneTree(max_length);
    00256
    00257     return true;
    00258   }
    00259
    00260 private :
    00261
    00262   unsigned max_length;
    00263   eoInit<EoType>& initializer;
    00264 };
    00265
    00271 template<class FType, class Node>
    00272 class eoCollapseSubtreeMutation: public eoMonOp< eoParseTree<FType, Node> >
    00273 {
    00274 public:
    00275
    00276   typedef eoParseTree<FType,Node> EoType;
    00282   eoCollapseSubtreeMutation(eoInit<EoType>& _init, unsigned _max_length)
    00283     : eoMonOp<EoType>(), max_length(_max_length), initializer(_init)
    00284   {};
    00285
    00287   virtual std::string className() const { return "eoCollapseSubtreeMutation"; };
    00288
    00290   virtual ~eoCollapseSubtreeMutation() {};
    00295   bool operator()(EoType& _eo1 )
    00296   {
    00297           int i = rng.random(_eo1.size());
    00298           // look for a subtree
    00299           while ((_eo1[i].arity() == 0) && (_eo1.size() > 1))
    00300           {
    00301                 i= rng.random(_eo1.size());
    00302           };
    00303
    00304           // create a new tree to
    00305           EoType eo2;
    00306           initializer(eo2);
    00307
    00308           int j = rng.random(eo2.size());
    00309           // make sure we select a subtree (and not a terminal)
    00310           while(eo2[j].arity() != 0)
    00311           {
    00312                 j = rng.random(eo2.size());
    00313           };
    00314
    00315           _eo1[i] = eo2[j]; // insert subtree
    00316
    00317           // we don't have to prune because the subtree is always smaller
    00318           _eo1.pruneTree(max_length);
    00319
    00320     return true;
    00321   }
    00322
    00323 private :
    00324
    00325   unsigned max_length;
    00326   eoInit<EoType>& initializer;
    00327 };
    00328
    00329
    00335 template<class FType, class Node>
    00336 class eoHoistMutation: public eoMonOp< eoParseTree<FType, Node> >
    00337 {
    00338 public:
    00339
    00340   typedef eoParseTree<FType,Node> EoType;
    00345   eoHoistMutation()
    00346     : eoMonOp<EoType>()
    00347   {};
    00348
    00350   virtual std::string className() const { return "eoHoistMutation"; };
    00351
    00353   virtual ~eoHoistMutation() {};
    00358   bool operator()(EoType& _eo1 )
    00359   {
    00360
    00361
    00362           // select a hoist point
    00363           int i = rng.random(_eo1.size());
    00364           // and create a new tree
    00365           EoType eo2(_eo1[i]);
    00366
    00367           // we don't have to prune because the new tree is always smaller
    00368           //_eo1.pruneTree(max_length);
    00369
    00370           _eo1 = eo2;
    00371
    00372     return true;
    00373   }
    00374
    00375 private :
    00376
    00377 };
    00378
    00379
    00380 #endif