EvolvingObjects
|
00001 // -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- 00002 00003 //----------------------------------------------------------------------------- 00004 // eoStParseTreeDepthInit.h : initializor strongly type GP 00005 // (c) Jeroen Eggermont 2001 00006 /* 00007 This library is free software; you can redistribute it and/or 00008 modify it under the terms of the GNU Lesser General Public 00009 License as published by the Free Software Foundation; either 00010 version 2 of the License, or (at your option) any later version. 00011 00012 This library is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 Lesser General Public License for more details. 00016 00017 You should have received a copy of the GNU Lesser General Public 00018 License along with this library; if not, write to the Free Software 00019 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00020 00021 Contact: todos@geneura.ugr.es, http://geneura.ugr.es 00022 jeggermo@liacs.nl 00023 00024 */ 00025 //----------------------------------------------------------------------------- 00026 00027 #ifndef eoStParseTreeDepthInit_h 00028 #define eoStParseTreeDepthInit_h 00029 00030 #include <EO.h> 00031 #include <gp/eoParseTree.h> 00032 #include <eoInit.h> 00033 #include <eoOp.h> 00034 00035 #include <map> 00036 00037 using namespace gp_parse_tree; 00038 00039 #define TERMINAL 0 00040 00041 #define NONTERMINAL 4 00042 #define ALL 5 00043 00063 template <class FType, class Node> 00064 class eoStParseTreeDepthInit : public eoInit< eoParseTree<FType, Node> > 00065 { 00066 public : 00067 00068 typedef eoParseTree<FType, Node> EoType; 00069 00077 eoStParseTreeDepthInit( 00078 unsigned _max_depth, 00079 const std::vector<Node>& _node, 00080 const int& _return_type, 00081 bool _grow = true) 00082 : 00083 eoInit<EoType>(), 00084 max_depth(_max_depth), 00085 return_type(_return_type), 00086 grow(_grow) 00087 { 00088 if(_node.empty()) 00089 { 00090 throw std::logic_error("eoStParseTreeDepthInit: uhm, wouldn't you rather give a non-empty set of Nodes?"); 00091 } 00092 00093 00094 unsigned int i=0; 00095 int arity=0; 00096 int type=0; 00097 std::vector<Node> node_vector; 00098 for(i=0; i < _node.size(); i++) 00099 { 00100 arity = _node[i].arity(); 00101 type = _node[i].type(); 00102 if(arity==0) 00103 { 00104 node_vector = node[type][TERMINAL]; 00105 node_vector.push_back(_node[i]); 00106 node[type][TERMINAL]= node_vector; 00107 } 00108 else 00109 //if (arity != 0) // non-terminal 00110 { 00111 node_vector = node[type][NONTERMINAL]; 00112 node_vector.push_back(_node[i]); 00113 node[type][NONTERMINAL] = node_vector; 00114 } 00115 node_vector = node[type][ALL]; 00116 node_vector.push_back(_node[i]); 00117 node[type][ALL] = node_vector; 00118 00119 } 00120 00121 00122 } 00124 virtual std::string className() const { return "eoStParseTreeDepthInit"; }; 00125 00129 void operator()(EoType& _tree) 00130 { 00131 std::list<Node> sequence; 00132 bool good_tree = false; 00133 do 00134 { 00135 sequence.clear(); 00136 good_tree = generate(sequence, max_depth, return_type); 00137 }while (!good_tree); 00138 00139 parse_tree<Node> tmp(sequence.begin(), sequence.end()); 00140 _tree.swap(tmp); 00141 } 00142 private : 00143 bool generate(std::list<Node>& sequence, int the_max, int request_type) 00144 { 00145 00146 int selected=0; 00147 bool ok = true; 00148 00149 if (the_max == 1) 00150 { // generate terminals only 00151 if( node[request_type][TERMINAL].empty() ) // no possible terminal node of this type 00152 return false; // we have an invalid tree 00153 else 00154 { 00155 selected = rng.random((node[request_type][TERMINAL]).size()); 00156 sequence.push_front(node[request_type][TERMINAL][selected]); 00157 return true; 00158 } 00159 00160 } 00161 00162 int arity=0; 00163 if (grow) 00164 { 00165 selected = rng.random((node[request_type][ALL]).size()); 00166 arity = node[request_type][ALL][selected].arity(); 00167 sequence.push_front(node[request_type][ALL][selected]); 00168 for (int i = 0; i < arity; ++i) 00169 ok &= generate(sequence, the_max - 1, node[request_type][ALL][selected].type(i)); 00170 } 00171 else // full 00172 { 00173 selected = rng.random((node[request_type][NONTERMINAL]).size()); 00174 arity = node[request_type][NONTERMINAL][selected].arity(); 00175 sequence.push_front(node[request_type][NONTERMINAL][selected]); 00176 for (int i = 0; i < arity; ++i) 00177 ok &=generate(sequence, the_max - 1, node[request_type][NONTERMINAL][selected].type(i)); 00178 } 00179 00180 return ok; 00181 00182 } 00183 00184 00185 00186 00187 unsigned max_depth; 00188 std::map < int, std::map < int, std::vector<Node> > > node; 00189 00190 int return_type; 00191 bool grow; 00192 }; 00193 00194 #endif