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