# 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
    00036 using namespace gp_parse_tree;
    00037
    00038 #define TERMINAL 0
    00039
    00040 #define NONTERMINAL 4
    00041 #define ALL 5
    00042
    00060 template <class FType, class Node>
    00061 class eoStParseTreeDepthInit : public eoInit< eoParseTree<FType, Node> >
    00062 {
    00063     public :
    00064
    00065     typedef eoParseTree<FType, Node> EoType;
    00066
    00073         eoStParseTreeDepthInit(
    00074         unsigned _max_depth,
    00075                 const std::vector<Node>& _node,
    00076                 const int& _return_type,
    00077         bool _grow = true)
    00078             :
    00079             eoInit<EoType>(),
    00080                         max_depth(_max_depth),
    00081                         return_type(_return_type),
    00082                         grow(_grow)
    00083     {
    00084       if(_node.empty())
    00085       {
    00086         throw std::logic_error("eoStParseTreeDepthInit: uhm, wouldn't you rather give a non-empty set of Nodes?");
    00087       }
    00088
    00089
    00090       unsigned int i=0;
    00091       int arity=0;
    00092       int type=0;
    00093       std::vector<Node> node_std::vector;
    00094       for(i=0; i < _node.size(); i++)
    00095       {
    00096         arity = _node[i].arity();
    00097         type = _node[i].type();
    00098         if(arity==0)
    00099         {
    00100                 node_std::vector = node[type][TERMINAL];
    00101                 node_std::vector.push_back(_node[i]);
    00102                 node[type][TERMINAL]= node_std::vector;
    00103         }
    00104         else
    00105         //if (arity != 0) // non-terminal
    00106         {
    00107                 node_std::vector = node[type][NONTERMINAL];
    00108                 node_std::vector.push_back(_node[i]);
    00109                 node[type][NONTERMINAL] = node_std::vector;
    00110         }
    00111         node_std::vector = node[type][ALL];
    00112         node_std::vector.push_back(_node[i]);
    00113         node[type][ALL] = node_std::vector;
    00114
    00115       }
    00116
    00117
    00118     }
    00120         virtual std::string className() const { return "eoStParseTreeDepthInit"; };
    00121
    00125     void operator()(EoType& _tree)
    00126         {
    00127                 std::list<Node> sequence;
    00128                 bool good_tree = false;
    00129                 do
    00130                 {
    00131                         sequence.clear();
    00132                         good_tree = generate(sequence, max_depth, return_type);
    00133                 }while (!good_tree);
    00134
    00135                 parse_tree<Node> tmp(sequence.begin(), sequence.end());
    00136                 _tree.swap(tmp);
    00137         }
    00138    private :
    00139     bool generate(std::list<Node>& sequence, int the_max, int request_type)
    00140     {
    00141
    00142             int selected=0;
    00143             bool ok = true;
    00144
    00145             if (the_max == 1)
    00146             { // generate terminals only
    00147                 if( node[request_type][TERMINAL].empty() ) // no possible terminal node of this type
    00148                         return false; // we have an invalid tree
    00149                 else
    00150                 {
    00151                         selected = rng.random((node[request_type][TERMINAL]).size());
    00152                         sequence.push_front(node[request_type][TERMINAL][selected]);
    00153                         return true;
    00154                 }
    00155
    00156             }
    00157
    00158             int arity=0;
    00159             if (grow)
    00160             {
    00161                 selected = rng.random((node[request_type][ALL]).size());
    00162                 arity = node[request_type][ALL][selected].arity();
    00163                 sequence.push_front(node[request_type][ALL][selected]);
    00164                 for (int i = 0; i < arity; ++i)
    00165                     ok &= generate(sequence, the_max - 1, node[request_type][ALL][selected].type(i));
    00166             }
    00167             else // full
    00168             {
    00169                  selected = rng.random((node[request_type][NONTERMINAL]).size());
    00170                  arity = node[request_type][NONTERMINAL][selected].arity();
    00171                  sequence.push_front(node[request_type][NONTERMINAL][selected]);
    00172                  for (int i = 0; i < arity; ++i)
    00173                      ok &=generate(sequence, the_max - 1, node[request_type][NONTERMINAL][selected].type(i));
    00174             }
    00175
    00176             return ok;
    00177
    00178     }
    00179
    00180
    00181
    00182
    00183         unsigned max_depth;
    00184         map < int, map < int, std::vector<Node> > > node;
    00185
    00186         int return_type;
    00187         bool grow;
    00188 };
    00189
    00190 #endif