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

Generated on Thu Oct 19 05:06:38 2006 for EO by  doxygen 1.3.9.1