#ifndef EO_PARSE_TREE_H #define EO_PARSE_TREE_H #include #include #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 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) {} 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 eoGeneralOp< eoParseTree > { public: typedef eoParseTree EoType; eoSubtreeXOver( unsigned _max_length) : eoGeneralOp(), max_length(_max_length) {}; virtual string className() const { return "eoSubtreeXOver"; }; /// Dtor virtual ~eoSubtreeXOver () {}; void operator()(eoIndiSelector& _select, eoInserter& _insert ) { EoType eo1 = _select(); const EoType& eo2 = _select(); int i = rng.random(eo1.size()); int j = rng.random(eo2.size()); eo1[i] = eo2[j]; // insert subtree eo1.pruneTree(max_length); eo1.invalidate(); _insert(eo1); } unsigned max_length; }; template class eoBranchMutation: public eoGeneralOp< eoParseTree > { public: typedef eoParseTree EoType; eoBranchMutation(eoInit& _init, unsigned _max_length) : eoGeneralOp(), max_length(_max_length), initializer(_init) {}; virtual string className() const { return "eoBranchMutation"; }; /// Dtor virtual ~eoBranchMutation() {}; void operator()(eoIndiSelector& _select, eoInserter& _insert ) { EoType eo1 = _select(); 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); eo1.invalidate(); _insert(eo1); } private : unsigned max_length; eoInit& initializer; }; #endif