#ifndef EO_PARSE_TREE_H #define EO_PARSE_TREE_H #include #include "EO.h" #include "eoOp.h" #include "eoInserter.h" #include "eoIndiSelector.h" #include "parse_tree.h" #include "eoRnd.h" using namespace gp_parse_tree; using namespace std; template class eoParseTree : public EO, public parse_tree { public : typedef typename parse_tree::subtree Type; eoParseTree(void) : EO(), parse_tree() {} eoParseTree(unsigned _size, eoRnd& _rnd) : EO(), parse_tree(_rnd()) { pruneTree(_size); } eoParseTree(eoRnd& _rnd) : EO(), parse_tree(_rnd()) {} virtual void pruneTree(unsigned _size) { if (_size < 1) return; if (size() > _size) { Type* sub = &operator[](size() - 2); // prune tree while (sub->size() > _size) { sub = &sub->operator[](0); } back() = *sub; } } 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 eoRnd< eoParseTree::Type > { public : typedef eoParseTree EoType; eoGpDepthInitializer( unsigned _max_depth, const vector& _initializor, bool _grow = true) : eoRnd(), max_depth(_max_depth), initializor(_initializor), grow(_grow) {} virtual string className() const { return "eoDepthInitializer"; }; EoType::Type operator()(void) { list sequence; generate(sequence, max_depth); parse_tree tree(sequence.begin(), sequence.end()); return tree.root(); } 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& _source, eoInserter& _sink ) const { EoType eo1 = _source.select(); const EoType& eo2 = _source.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(); _sink.insert(eo1); } unsigned max_length; }; template class eoBranchMutation: public eoGeneralOp< eoParseTree > { public: typedef eoParseTree EoType; eoBranchMutation(eoRnd& _init, unsigned _max_length) : eoGeneralOp(), max_length(_max_length), initializer(_init) {}; virtual string className() const { return "eoBranchMutation"; }; /// Dtor virtual ~eoBranchMutation() {}; void operator()(eoIndiSelector& _source, eoInserter& _sink ) const { EoType eo1 = _source.select(); int i = rng.random(eo1.size()); EoType eo2(eo1[i].size(), initializer); // create random other to cross with eo1[i] = eo2.back(); // insert subtree eo1.pruneTree(max_length); eo1.invalidate(); _sink.insert(eo1); } private : unsigned max_length; eoRnd& initializer; }; #endif