EvolvingObjects
eoStParseTreeDepthInit.h
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
 All Classes Namespaces Files Functions Variables Typedefs Friends