EvolvingObjects
|
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