/* -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- ----------------------------------------------------------------------------- eoWrappedOps.h Derived from the General genetic operator, which can be used to wrap any unary or binary operator. File also contains the eoCombinedOp, needed by the eoSequentialGOpSelector (c) Maarten Keijzer (mak@dhi.dk) and GeNeura Team, 1999, 2000 This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Contact: todos@geneura.ugr.es, http://geneura.ugr.es */ //----------------------------------------------------------------------------- #ifndef eoWrappedOps_h #define eoWrappedOps_h //----------------------------------------------------------------------------- #include // eoOp, eoMonOp, eoBinOp #include using namespace std; /// Wraps monary operators template class eoWrappedMonOp : public eoGeneralOp { public : /// eoWrappedMonOp(eoMonOp& _op) : eoGeneralOp(), op(_op) {}; /// virtual ~eoWrappedMonOp() {} /// Instantiates the abstract method void operator()( eoIndiSelector& _in, eoInserter& _out) { EOT result = _in(); op( result ); _out(result); } private : eoMonOp& op; }; /// Wraps binary operators template class eoWrappedBinOp : public eoGeneralOp { public : /// eoWrappedBinOp(eoBinOp& _op) : eoGeneralOp(), op(_op) {} /// virtual ~eoWrappedBinOp() {} /// Instantiates the abstract method. EOT should have copy ctor. void operator()(eoIndiSelector& _in, eoInserter& _out) { EOT out1 = _in(); const EOT& out2 = _in(); op(out1, out2); _out(out1); } private : eoBinOp& op; }; /// Wraps Quadratic operators template class eoWrappedQuadraticOp : public eoGeneralOp { public : /// eoWrappedQuadraticOp(eoQuadraticOp& _op) : eoGeneralOp(), op(_op) {} /// virtual ~eoWrappedQuadraticOp() {} /// Instantiates the abstract method. EOT should have copy ctor. void operator()(eoIndiSelector& _in, eoInserter& _out) { EOT out1 = _in(); EOT out2 = _in(); op(out1, out2); _out(out1)(out2); } private : eoQuadraticOp& op; }; #include template class eoCombinedOp : public eoGeneralOp { public : eoCombinedOp(const std::vector*>& _ops, const std::vector& rates) : ops(_ops), rates(_rates) {} class eoDelayedSelector : public eoIndiSelector { public : eoDelayedSelector(eoIndiSelector& _select, const eoPop& _pop) : select(_select), pop(_pop), it(pop.begin()) {} unsigned size() const { return select.size();} const EOT& operator[](size_t i) const { return select[i]; } /// will first dispense all previously selected individuals before returning new ones const EOT& operator()(void) { if (it == pop.end()) { return select(); } // else return *it++; } eoPop::const_iterator get_it(void) const { return it; } private : eoIndiSelector& select; const eoPop& pop; eoPop::const_iterator it; }; /** Applies all ops in the combined op It works in the following way */ void operator()( eoIndiSelector& _in, eoInserter& _out ) { eoPop intermediate; eoPop next; unsigned i; for (i = 0; i < ops.size(); ++i) { eoDelayedSelector delay(_in, intermediate); inserter.bind(next); unsigned counter = 0; // apply operators until we have as many outputs as inputs do { if (flip(rates[i])) // should this flip be here? (*ops[i])(delayedSelector, inserter); counter++; if (counter > 1000) { throw logical_error("eoCombinedOp: no termination after 1000 tries, did you forget to insert individuals in your eoGeneralOp?"); } } while (next.size() < intermediate.size()); intermediate.swap(next); next.resize(0); } // after last swap, results can be found in intermediate for (i = 0; i < intermediate.size(); ++i) _out(intermediate[i]); } private : const std::vector*>& ops; const std::vector rates; eoBackInserter inserter; }; #endif