EvolvingObjects
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 #include <set>
00036 
00037 #include <gp/eoParseTree.h>
00038 
00039 // a help function
00040 template <class EOT>
00041 void get_possible_nodes(const EOT &_eo, std::vector<int> &possible_nodes, const int type)
00042 {
00043         int n=0;
00044         possible_nodes.clear();
00045         // collect the possible crossover points in _eo (nodes with the same type)
00046         for(n=0; n < _eo.size(); n++)
00047                 if (type == _eo[n]->type())
00048                         possible_nodes.push_back(n);
00049 }
00050 
00051 
00056 template<class FType, class Node>
00057 class eoStSubtreeXOver: public eoQuadOp< eoParseTree<FType, Node> > {
00058 public:
00059 
00060   typedef eoParseTree<FType,Node> EoType;
00065   eoStSubtreeXOver( unsigned _max_length)
00066     : eoQuadOp<EoType>(), max_length(_max_length) {};
00067 
00069   virtual std::string className() const { return "eoStSubtreeXOver"; };
00070 
00072   virtual ~eoStSubtreeXOver () {};
00073 
00079   bool operator()(EoType & _eo1, EoType & _eo2 )
00080   {
00081           int i = 0;
00082           std::vector<int> nodes;
00083           int n = 0;
00084           int type = 0;
00085           int j = 0;
00086           std::set<int> test;
00087           do
00088           {
00089                 do // select a random node in _eo1 as crossover point, and check if we didn't try it already
00090                 {
00091                         i = rng.random(_eo1.size());
00092                 }while(test.count(i) > 0);
00093 
00094                 test.insert(i);
00095 
00096                 type = _eo1[i]->type();
00097 
00098                 get_possible_nodes<EoType>(_eo2, nodes, type);
00099 
00100          }while(nodes.empty() && (test.size() < _eo1.size()));
00101 
00102          if (nodes.empty()) // we failed to select a crossover point but tried all points (test.size() == _eo1.size()).
00103                 return true;  // should this be false ??
00104 
00105          // we did find at least one possible crossover point in _eo2
00106 
00107          n = rng.random(nodes.size());
00108          j = nodes[n];
00109 
00110 
00111 
00112          typename eoParseTree<FType, Node>::subtree tmp = _eo1[i];
00113          _eo1[i] = _eo2[j]; // insert subtree
00114          _eo2[j] = tmp;
00115 
00116          // we can't prune anymore
00117          /*
00118          _eo1.pruneTree(max_length);
00119          _eo2.pruneTree(max_length);
00120          */
00121 
00122          return true;
00123   }
00124  private:
00125   unsigned max_length;
00126 };
00127 
00132 template<class FType, class Node>
00133 class eoStBranchMutation: public eoMonOp< eoParseTree<FType, Node> >
00134 {
00135 public:
00136 
00137   typedef eoParseTree<FType,Node> EoType;
00143   eoStBranchMutation(eoInit<EoType>& _init, unsigned _max_length)
00144     : eoMonOp<EoType>(), max_length(_max_length), initializer(_init)
00145   {};
00146 
00148   virtual std::string className() const { return "eoStBranchMutation"; };
00149 
00151   virtual ~eoStBranchMutation() {};
00152 
00157   bool operator()(EoType& _eo1 )
00158   {
00159           int i = rng.random(_eo1.size());
00160           std::vector<int> nodes;
00161           int type = _eo1[i]->type();
00162           int j=0;
00163           int n=0;
00164 
00165           EoType eo2;
00166 
00167           do
00168           {
00169                 initializer(eo2);
00170                 get_possible_nodes(eo2, nodes, type);
00171           }while (nodes.empty());
00172 
00173           n = rng.random(nodes.size());
00174           j = nodes[n];
00175 
00176           _eo1[i] = eo2[j]; // insert subtree
00177 
00178           // no more pruning
00179           /*
00180           _eo1.pruneTree(max_length);
00181           */
00182 
00183     return true;
00184   }
00185 
00186 private :
00187 
00188   unsigned max_length;
00189   eoInit<EoType>& initializer;
00190 };
00191 
00192 
00197 template<class FType, class Node>
00198 class eoStPointMutation: public eoMonOp< eoParseTree<FType, Node> >
00199 {
00200 public:
00201 
00202   typedef eoParseTree<FType,Node> EoType;
00203 
00208   eoStPointMutation( std::vector<Node>& _node)
00209     : eoMonOp<EoType>()
00210   {
00211         unsigned int i=0;
00212         int arity=0;
00213         int type=0;
00214         std::vector<Node> node_vector;
00215         for(i=0; i < _node.size(); i++)
00216         {
00217                 arity = _node[i].arity();
00218                 type = _node[i].type();
00219 
00220                         node_vector = node[type][arity];
00221                         node_vector.push_back(_node[i]);
00222                         node[type][arity]= node_vector;
00223 
00224         };
00225   };
00226 
00228   virtual std::string className() const { return "eoStPointMutation"; };
00229 
00231   virtual ~eoStPointMutation() {};
00232 
00237   bool operator()(EoType& _eo1 )
00238   {
00239         // select a random node i that is to be mutated
00240         int i = rng.random(_eo1.size());
00241         int arity = _eo1[i].arity();
00242         int type = _eo1[i]->type();
00243         int j = rng.random(node[type][arity].size());
00244 
00245 
00246         _eo1[i] = node[type][arity][j];
00247         return true;
00248   }
00249 
00250 private :
00251 
00252         std::map < int, std::map < int, std::vector<Node> > > node;
00253 };
00254 
00255 
00260 template<class FType, class Node>
00261 class eoStHoistMutation: public eoMonOp< eoParseTree<FType, Node> >
00262 {
00263 public:
00264 
00265   typedef eoParseTree<FType,Node> EoType;
00271   eoStHoistMutation(eoInit<EoType>& _init, unsigned _max_length)
00272     : eoMonOp<EoType>(), max_length(_max_length), initializer(_init)
00273   {};
00274 
00276   virtual std::string className() const { return "eoStHoistMutation"; };
00277 
00279   virtual ~eoStHoistMutation() {};
00280 
00285   bool operator()(EoType& _eo1 )
00286   {
00287 
00288           std::vector<int> nodes;
00289           // get the type of the current tree
00290           int type = _eo1[ _eo1.size() - 1 ]->type();
00291 
00292           get_possible_nodes(_eo1, nodes, type);
00293 
00294           // select a subtree-node to replace the current tree
00295           int n = rng.random(nodes.size());
00296           int i = nodes[n];
00297 
00298           EoType eo2(_eo1[i]);
00299 
00300           _eo1 = eo2;
00301 
00302           return true;
00303   }
00304 
00305 private :
00306 
00307   unsigned max_length;
00308   eoInit<EoType>& initializer;
00309 };
00310 
00311 
00312 #endif
 All Classes Namespaces Files Functions Variables Typedefs Friends