#ifndef EO_PARSE_TREE_H #define EO_PARSE_TREE_H #include #include #include #include #include using namespace gp_parse_tree; using namespace std; template class eoParseTree : public EO, public parse_tree { public : typedef parse_tree::subtree Subtree; eoParseTree(void) {} eoParseTree(const parse_tree& tree) : parse_tree(tree) {} virtual void pruneTree(unsigned _size) { if (_size < 1) return; while (size() > _size) { back() = operator[](size()-2); } } eoParseTree(std::istream& is) : EO(), parse_tree() { readFrom(is); } string className(void) const { return "eoParseTree"; } void printOn(std::ostream& os) const { os << fitness() << ' '; std::copy(ebegin(), eend(), ostream_iterator(os)); } void readFrom(std::istream& is) { FType fit; is >> fit; fitness(fit); std::copy(istream_iterator(is), istream_iterator(), back_inserter(*this)); } }; template std::ostream& operator<<(std::ostream& os, const eoParseTree& eot) { eot.printOn(os); return os; } template std::istream& operator>>(std::istream& is, eoParseTree& eot) { eot.readFrom(is); return is; } template bool lt_arity(const Node &node1, const Node &node2) { return (node1.arity() < node2.arity()); } template class eoGpDepthInitializer : public eoInit< eoParseTree > { public : typedef eoParseTree EoType; eoGpDepthInitializer( unsigned _max_depth, const vector& _initializor, bool _grow = true) : eoInit(), max_depth(_max_depth), initializor(_initializor), grow(_grow) { if(initializor.empty()) { throw logic_error("eoGpDepthInitializer: uhm, wouldn't you rather give a non-empty set of Nodes?"); } // lets sort the initializor vector according to arity (so we can be sure the terminals are in front) // we use stable_sort so that if element i was in front of element j and they have the same arity i remains in front of j stable_sort(initializor.begin(), initializor.end(), lt_arity); } virtual string className() const { return "eoDepthInitializer"; }; void operator()(EoType& _tree) { list sequence; generate(sequence, max_depth); parse_tree tmp(sequence.begin(), sequence.end()); _tree.swap(tmp); } void generate(list& sequence, int the_max, int last_terminal = -1) { if (last_terminal == -1) { // check where the last terminal in the sequence resides vector::iterator it; for (it = initializor.begin(); it != initializor.end(); ++it) { if (it->arity() > 0) break; } last_terminal = it - initializor.begin(); } if (the_max == 1) { // generate terminals only vector::iterator it = initializor.begin() + rng.random(last_terminal); sequence.push_front(*it); return; } vector::iterator what_it; if (grow) { what_it = initializor.begin() + rng.random(initializor.size()); } else // full { what_it = initializor.begin() + last_terminal + rng.random(initializor.size() - last_terminal); } what_it->randomize(); sequence.push_front(*what_it); for (int i = 0; i < what_it->arity(); ++i) generate(sequence, the_max - 1, last_terminal); } private : unsigned max_depth; std::vector initializor; bool grow; }; template class eoSubtreeXOver: public eoQuadOp< eoParseTree > { public: typedef eoParseTree EoType; eoSubtreeXOver( unsigned _max_length) : eoQuadOp(), max_length(_max_length) {}; virtual string className() const { return "eoSubtreeXOver"; }; /// Dtor virtual ~eoSubtreeXOver () {}; bool operator()(EoType & _eo1, EoType & _eo2 ) { int i = rng.random(_eo1.size()); int j = rng.random(_eo2.size()); parse_tree::subtree tmp = _eo1[i]; _eo1[i] = _eo2[j]; // insert subtree _eo2[j] = tmp; _eo1.pruneTree(max_length); _eo2.pruneTree(max_length); return true; } unsigned max_length; }; template class eoBranchMutation: public eoMonOp< eoParseTree > { public: typedef eoParseTree EoType; eoBranchMutation(eoInit& _init, unsigned _max_length) : eoMonOp(), max_length(_max_length), initializer(_init) {}; virtual string className() const { return "eoBranchMutation"; }; /// Dtor virtual ~eoBranchMutation() {}; bool operator()(EoType& _eo1 ) { int i = rng.random(_eo1.size()); EoType eo2; initializer(eo2); int j = rng.random(eo2.size()); _eo1[i] = eo2[j]; // insert subtree _eo1.pruneTree(max_length); return true; } private : unsigned max_length; eoInit& initializer; }; #endif