# eoStParseTreeOp.h

    00001 // -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
    00002
    00003 //-----------------------------------------------------------------------------
    00004 // eoStParseTreeOp.h : crossover and mutation operators for  the strongly typed GP
    00005 // (c) Jeroen Eggermont 2001 for other mutation operators
    00006
    00007 /*
    00008     This library is free software; you can redistribute it and/or
    00009     modify it under the terms of the GNU Lesser General Public
    00010     License as published by the Free Software Foundation; either
    00011     version 2 of the License, or (at your option) any later version.
    00012
    00013     This library is distributed in the hope that it will be useful,
    00014     but WITHOUT ANY WARRANTY; without even the implied warranty of
    00015     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00016     Lesser General Public License for more details.
    00017
    00018     You should have received a copy of the GNU Lesser General Public
    00019     License along with this library; if not, write to the Free Software
    00020     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    00021
    00022     Contact: todos@geneura.ugr.es, http://geneura.ugr.es
    00023              mak@dhi.dk
    00024              jeggermo@liacs.nl
    00025  */
    00026 //-----------------------------------------------------------------------------
    00027
    00028 #ifndef eoStParseTreeOp_h
    00029 #define eoStParseTreeOp_h
    00030
    00031 #include <EO.h>
    00032 #include <eoOp.h>
    00033 #include <map.h>
    00034 #include <iostream>
    00035
    00036 #include <gp/eoParseTree.h>
    00037
    00038 // a help function
    00039 template <class EOT>
    00040 void get_possible_nodes(const EOT &_eo, std::vector<int> &possible_nodes, const int type)
    00041 {
    00042         int n=0;
    00043         possible_nodes.clear();
    00044         // collect the possible crossover points in _eo (nodes with the same type)
    00045         for(n=0; n < _eo.size(); n++)
    00046                 if (type == _eo[n]->type())
    00047                         possible_nodes.push_back(n);
    00048 }
    00049
    00050
    00055 template<class FType, class Node>
    00056 class eoStSubtreeXOver: public eoQuadOp< eoParseTree<FType, Node> > {
    00057 public:
    00058
    00059   typedef eoParseTree<FType,Node> EoType;
    00064   eoStSubtreeXOver( unsigned _max_length)
    00065     : eoQuadOp<EoType>(), max_length(_max_length) {};
    00066
    00068   virtual std::string className() const { return "eoStSubtreeXOver"; };
    00069
    00071   virtual ~eoStSubtreeXOver () {};
    00072
    00078   bool operator()(EoType & _eo1, EoType & _eo2 )
    00079   {
    00080           int i = 0;
    00081           std::vector<int> nodes;
    00082           int n = 0;
    00083           int type = 0;
    00084           int j = 0;
    00085           set<int> test;
    00086           do
    00087           {
    00088                 do // select a random node in _eo1 as crossover point, and check if we didn't try it already
    00089                 {
    00090                         i = rng.random(_eo1.size());
    00091                 }while(test.count(i) > 0);
    00092
    00093                 test.insert(i);
    00094
    00095                 type = _eo1[i]->type();
    00096
    00097                 get_possible_nodes<EoType>(_eo2, nodes, type);
    00098
    00099          }while(nodes.empty() && (test.size() < _eo1.size()));
    00100
    00101          if (nodes.empty()) // we failed to select a crossover point but tried all points (test.size() == _eo1.size()).
    00102                 return true;  // should this be false ??
    00103
    00104          // we did find at least one possible crossover point in _eo2
    00105
    00106          n = rng.random(nodes.size());
    00107          j = nodes[n];
    00108
    00109          parse_tree<Node>::subtree tmp = _eo1[i];
    00110          _eo1[i] = _eo2[j]; // insert subtree
    00111          _eo2[j] = tmp;
    00112
    00113          // we can't prune anymore
    00114          /*
    00115          _eo1.pruneTree(max_length);
    00116          _eo2.pruneTree(max_length);
    00117          */
    00118
    00119          return true;
    00120   }
    00121  private:
    00122   unsigned max_length;
    00123 };
    00124
    00129 template<class FType, class Node>
    00130 class eoStBranchMutation: public eoMonOp< eoParseTree<FType, Node> >
    00131 {
    00132 public:
    00133
    00134   typedef eoParseTree<FType,Node> EoType;
    00140   eoStBranchMutation(eoInit<EoType>& _init, unsigned _max_length)
    00141     : eoMonOp<EoType>(), max_length(_max_length), initializer(_init)
    00142   {};
    00143
    00145   virtual std::string className() const { return "eoStBranchMutation"; };
    00146
    00148   virtual ~eoStBranchMutation() {};
    00149
    00154   bool operator()(EoType& _eo1 )
    00155   {
    00156           int i = rng.random(_eo1.size());
    00157           std::vector<int> nodes;
    00158           int type = _eo1[i]->type();
    00159           int j=0;
    00160           int n=0;
    00161
    00162           EoType eo2;
    00163
    00164           do
    00165           {
    00166                 initializer(eo2);
    00167                 get_possible_nodes(eo2, nodes, type);
    00168           }while (nodes.empty());
    00169
    00170           n = rng.random(nodes.size());
    00171           j = nodes[n];
    00172
    00173           _eo1[i] = eo2[j]; // insert subtree
    00174
    00175           // no more pruning
    00176           /*
    00177           _eo1.pruneTree(max_length);
    00178           */
    00179
    00180     return true;
    00181   }
    00182
    00183 private :
    00184
    00185   unsigned max_length;
    00186   eoInit<EoType>& initializer;
    00187 };
    00188
    00189
    00194 template<class FType, class Node>
    00195 class eoStPointMutation: public eoMonOp< eoParseTree<FType, Node> >
    00196 {
    00197 public:
    00198
    00199   typedef eoParseTree<FType,Node> EoType;
    00200
    00205   eoStPointMutation( std::vector<Node>& _node)
    00206     : eoMonOp<EoType>()
    00207   {
    00208         unsigned int i=0;
    00209         int arity=0;
    00210         int type=0;
    00211         std::vector<Node> node_std::vector;
    00212         for(i=0; i < _node.size(); i++)
    00213         {
    00214                 arity = _node[i].arity();
    00215                 type = _node[i].type();
    00216
    00217                         node_std::vector = node[type][arity];
    00218                         node_std::vector.push_back(_node[i]);
    00219                         node[type][arity]= node_std::vector;
    00220
    00221         };
    00222   };
    00223
    00225   virtual std::string className() const { return "eoStPointMutation"; };
    00226
    00228   virtual ~eoStPointMutation() {};
    00229
    00234   bool operator()(EoType& _eo1 )
    00235   {
    00236         // select a random node i that is to be mutated
    00237         int i = rng.random(_eo1.size());
    00238         int arity = _eo1[i].arity();
    00239         int type = _eo1[i]->type();
    00240         int j = rng.random(node[type][arity].size());
    00241
    00242
    00243         _eo1[i] = node[type][arity][j];
    00244         return true;
    00245   }
    00246
    00247 private :
    00248
    00249         map < int, map < int, std::vector<Node> > > node;
    00250 };
    00251
    00252
    00257 template<class FType, class Node>
    00258 class eoStHoistMutation: public eoMonOp< eoParseTree<FType, Node> >
    00259 {
    00260 public:
    00261
    00262   typedef eoParseTree<FType,Node> EoType;
    00268   eoStHoistMutation(eoInit<EoType>& _init, unsigned _max_length)
    00269     : eoMonOp<EoType>(), max_length(_max_length), initializer(_init)
    00270   {};
    00271
    00273   virtual std::string className() const { return "eoStHoistMutation"; };
    00274
    00276   virtual ~eoStHoistMutation() {};
    00277
    00282   bool operator()(EoType& _eo1 )
    00283   {
    00284
    00285           std::vector<int> nodes;
    00286           // get the type of the current tree
    00287           int type = _eo1[ _eo1.size() - 1 ]->type();
    00288
    00289
    00290
    00291           do
    00292           {
    00293                 initializer(eo2);
    00294                 get_possible_nodes(eo2, nodes, type);
    00295           }while (nodes.empty());
    00296
    00297           // select a subtree-node to replace the current tree
    00298           int n = rng.random(nodes.size());
    00299           int i = nodes[n];
    00300
    00301           EoType eo2(_eo1[i]);
    00302
    00303           _eo1 = eo2;
    00304
    00305           return true;
    00306   }
    00307
    00308 private :
    00309
    00310   unsigned max_length;
    00311   eoInit<EoType>& initializer;
    00312 };
    00313
    00314
    00315 #endif