diff --git a/eo/src/eoG3Replacement.h b/eo/src/eoG3Replacement.h new file mode 100644 index 00000000..28928edf --- /dev/null +++ b/eo/src/eoG3Replacement.h @@ -0,0 +1,86 @@ +/** -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + + ----------------------------------------------------------------------------- + eoG3Replacement.h + (c) Maarten Keijzer, Marc Schoenauer, 2002 + + 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: Marc.Schoenauer@inria.fr + mkeijzer@dhi.dk + */ +//----------------------------------------------------------------------------- + +#ifndef _eoG3Replacement_h +#define _eoG3Replacement_h + + +//----------------------------------------------------------------------------- +#include +#include +#include +#include +#include +#include +//----------------------------------------------------------------------------- + +/** +eoG3Replacement is an eoReplacement: +- no strong elitism (is suppposed to be within a steady-state engine) +- choose N (2) parents RANDOMLY - remove them from the parent population +- merge offspring and the N removed parents +- select best N of this merged population +- put them back into parent population + +*/ + +template +class eoG3Replacement : public eoReplacement +{ +public: + eoG3Replacement(eoHowMany _howManyEliminatedParents = eoHowMany(2, false)) : + // split truncates the parents and returns eliminated parents + split(_howManyEliminatedParents, true), + // reduce truncates the offpsring and does not return eliminated guys + reduce(-_howManyEliminatedParents, false) + {} + + void operator()(eoPop & _parents, eoPop & _offspring) + { + eoPop temp; + split(_parents, temp); + unsigned toKeep = temp.size(); // how many to keep from merged populations + // merge temp into offspring + plus(temp, _offspring); // add temp to _offspring (a little inconsistent!) + + // reduce merged + reduce(_offspring, temp); // temp dummy arg. will not be modified + // minimla check: + if (_offspring.size() != toKeep) + { + cerr << "Les tailles " << _offspring.size() << " " << toKeep << endl; + throw runtime_error("eoG3Replacement: wrong number of remaining offspring"); + } + // and put back into _parents + plus(_offspring, _parents); + } + +private: + eoLinearTruncateSplit split; // few parents to truncate -> linear + eoTruncateSplit reduce; // supposedly many offspring to truncate + eoPlus plus; +}; + +#endif diff --git a/eo/src/eoMGGReplacement.h b/eo/src/eoMGGReplacement.h new file mode 100644 index 00000000..c87073c4 --- /dev/null +++ b/eo/src/eoMGGReplacement.h @@ -0,0 +1,109 @@ +/** -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + + ----------------------------------------------------------------------------- + eoMGGReplacement.h + (c) Maarten Keijzer, Marc Schoenauer, 2002 + + 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: Marc.Schoenauer@inria.fr + mkeijzer@dhi.dk + */ +//----------------------------------------------------------------------------- + +#ifndef _eoMGGReplacement_h +#define _eoMGGReplacement_h + + +//----------------------------------------------------------------------------- +#include +#include +#include +#include +#include +#include +//----------------------------------------------------------------------------- + +/** +eoMGGReplacement is an eoReplacement: +- choose N (2) parents RANDOMLY - remove them from the parent population +- select best offspring, add to parents +- merge (other?) offspring and the N removed parents +- select best N-1 of this merged population (detTournament only at the moment) +- put them back into parent population + +*/ + +template +class eoMGGReplacement : public eoReplacement +{ +public: + eoMGGReplacement(eoHowMany _howManyEliminatedParents = eoHowMany(2, false), + unsigned _tSize=2) : + // split truncates the parents and returns eliminated parents + split(_howManyEliminatedParents, true), + tSize(_tSize) + { + if (tSize < 2) + { + cout << "Warning, Size for eoDetTournamentTruncateSplit adjusted to 2\n"; + tSize = 2; + } + } + + void operator()(eoPop & _parents, eoPop & _offspring) + { + cout << "Entering MGGReplacement" << endl; + + eoPop temp; + split(_parents, temp); + unsigned toKeep = temp.size(); // how many to keep from merged populations + // minimal check + if (toKeep < 2) + throw runtime_error("Not enough parents killed in eoMGGReplacement"); + + // select best offspring + eoPop::iterator it = _offspring.it_best_element(); + // add to parents + _parents.push_back(*it); + // remove from offspring + _offspring.erase(it); + + // merge temp into offspring + plus(temp, _offspring); + cout << "MGGReplacement - after merge" << endl; + + // repeatedly add selected offspring to parents + for (unsigned i=0; i split; // few parents to truncate -> linear + eoPlus plus; + unsigned int tSize; +}; + +#endif diff --git a/eo/src/eoReduceMergeReduce.h b/eo/src/eoReduceMergeReduce.h new file mode 100644 index 00000000..3d1eee08 --- /dev/null +++ b/eo/src/eoReduceMergeReduce.h @@ -0,0 +1,143 @@ +/** -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + + ----------------------------------------------------------------------------- + eoReduceMergeReduce.h + (c) Maarten Keijzer, Marc Schoenauer, 2002 + + 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: Marc.Schoenauer@inria.fr + mkeijzer@dhi.dk + */ +//----------------------------------------------------------------------------- + +#ifndef _eoReduceMergeReduce_h +#define _eoReduceMergeReduce_h + + +//----------------------------------------------------------------------------- +#include +#include +#include +#include +#include +//----------------------------------------------------------------------------- + +/** +eoReduceMergeReduce is an eoReplacement: +- saves possible elite parents +- reduces rest of parents +- reduces offspring +- merges reduced populations +- reduces resulting merged pop if necessary + +*/ + +template +class eoReduceMergeReduce : public eoReplacement +{ +public: + eoReduceMergeReduce(eoHowMany _howManyElite, + bool _strongElitism, + eoHowMany _howManyReducedParents, + eoReduce & _reduceParents, + eoHowMany _howManyReducedOffspring, + eoReduce & _reduceOffspring, + eoReduce & _reduceFinal) : + howManyElite(_howManyElite), + strongElitism(_strongElitism), + howManyReducedParents(_howManyReducedParents), + howManyReducedOffspring (_howManyReducedOffspring), + reduceParents(_reduceParents), + reduceOffspring(_reduceOffspring), + reduceFinal(_reduceFinal) + {} + + void operator()(eoPop & _parents, eoPop & _offspring) + { + eoPop temp; + unsigned int finalPopSize = _parents.size(); + unsigned int offSize = _offspring.size(); + + unsigned int elite = howManyElite(finalPopSize); + if (elite) // some parents MUST be saved somewhere + { + temp.resize(elite); + _parents.nth_element(elite); + std::copy(_parents.begin(), _parents.begin()+elite, temp.begin()); + _parents.erase(_parents.begin(), _parents.begin()+elite); + } + + // the reduce steps. First the parents + unsigned reducedParentSize = howManyReducedParents(_parents.size()); + if (!reducedParentSize) + _parents.clear(); + else if (reducedParentSize != _parents.size()) + reduceParents(_parents, reducedParentSize); + + // then the offspring + unsigned reducedOffspringSize = howManyReducedOffspring(offSize); + if (!reducedOffspringSize) + throw runtime_error("No offspring left after reduction!"); + if (reducedOffspringSize != offSize) // need reduction + reduceOffspring(_offspring, reducedOffspringSize); + + // now merge reduced populations + _parents.resize(reducedParentSize + _offspring.size()); + std::copy(_offspring.begin(), _offspring.end(), + _parents.begin()+reducedParentSize); + + // reduce the resulting population + // size depends on elitism + if (elite && strongElitism) + { + if (_parents.size() != finalPopSize-elite) + reduceFinal(_parents, finalPopSize-elite); + // and put back the elite + unsigned oldPSize = _parents.size(); + _parents.resize(_parents.size()+elite); + std::copy(temp.begin(), temp.end(), _parents.begin()+oldPSize); + } + else + { // only reduce final pop to right size + if (_parents.size() != finalPopSize) + reduceFinal(_parents, finalPopSize); + if (elite) // then treat weak elitism + { + unsigned toSave = 0; + _parents.sort(); + EOT & eoLimit = _parents[elite-1]; + unsigned index=0; + while (temp[index++] > eoLimit) + toSave++; + if (toSave) + for (unsigned i=0; i weak elistism + eoHowMany howManyReducedParents; // if 0, no parent in final replacement + eoHowMany howManyReducedOffspring; // if 0, runtime_error + // the reducers + eoReduce & reduceParents; + eoReduce & reduceOffspring; + eoReduce & reduceFinal; +}; + +#endif diff --git a/eo/src/eoReduceSplit.h b/eo/src/eoReduceSplit.h new file mode 100644 index 00000000..9db344ed --- /dev/null +++ b/eo/src/eoReduceSplit.h @@ -0,0 +1,307 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// eoReduceSplit.h +// Base class for population-reducing classes - retaining the poor losers +// (c) GeNeura Team, 1998, Marc Schoenauer, 2002 +/* + 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: Marc.Schoenauer@inria.fr + */ +//----------------------------------------------------------------------------- + +#ifndef eoReduceSplit_h +#define eoReduceSplit_h + +//----------------------------------------------------------------------------- + +#include + +// EO includes +#include // eoPop +#include // eoReduce +#include + +/** + * eoReduceSplit: reduce the pop to the specified size + * AND eventually returns the eliminated guys +*/ +template class eoReduceSplit: public eoBF&, eoPop &, void > +{}; + +/** deterministic truncation method using sort */ +template +class eoTruncateSplit : public eoReduceSplit +{ +public: + /** Ctor: must provide amount of reduction, + and whether or not you need to return the eliminated guys + */ + eoTruncateSplit(eoHowMany _howMany, bool _returnEliminated = false): + howMany(_howMany), returnEliminated(_returnEliminated) {} + + /** do the jonb */ + void operator()(eoPop& _newgen, eoPop & _eliminated) + { + unsigned popSize = _newgen.size(); + unsigned eliminated = howMany(popSize); + if (!eliminated) // nothing to do + return ; + unsigned newsize = popSize - eliminated; + if (newsize < 0) + throw std::logic_error("eoTruncateSplit: Cannot truncate to a larger size!\n"); + + _newgen.nth_element(newsize); + + // save poor losers if necessary + if (returnEliminated) + for (unsigned i=0; i +class eoLinearTruncateSplit : public eoReduceSplit +{ +public: + /** Ctor: must provide amount of reduction, + and whether or not you need to return the eliminated guys + */ + eoLinearTruncateSplit(eoHowMany _howMany, bool _returnEliminated = false): + howMany(_howMany), returnEliminated(_returnEliminated) {} + + /** do the job */ + void operator()(eoPop& _newgen, eoPop & _eliminated) + { + unsigned popSize = _newgen.size(); + unsigned eliminated = howMany(popSize); + if (!eliminated) // nothing to do + return ; + unsigned newsize = popSize - eliminated; + if (newsize < 0) + throw std::logic_error("eoLinearTruncateSplit: Cannot truncate to a larger size!\n"); + + _eliminated.reserve(_eliminated.size()+eliminated); //in case not empty? + for (unsigned i=0; i::iterator it = _newgen.it_worse_element(); + if (returnEliminated) + _eliminated.push_back(*it); + _newgen.erase(it); + } + } + +private: + eoHowMany howMany; + bool returnEliminated; +}; + +/** random truncation - batch version */ +template +class eoRandomSplit : public eoReduceSplit +{ +public: + /** Ctor: must provide amount of reduction, + and whether or not you need to return the eliminated guys + */ + eoRandomSplit(eoHowMany _howMany, bool _returnEliminated = false): + howMany(_howMany), returnEliminated(_returnEliminated) {} + + /** do the job */ + void operator()(eoPop& _newgen, eoPop & _eliminated) + { + unsigned popSize = _newgen.size(); + unsigned eliminated = howMany(popSize); + if (!eliminated) // nothing to do + return ; + unsigned newsize = popSize - eliminated; + if (newsize < 0) + throw std::logic_error("eoRandomSplit: Cannot truncate to a larger size!\n"); + + _newgen.shuffle(); + + // save poor losers if necessary + if (returnEliminated) + for (unsigned i=0; i +class eoLinearRandomSplit : public eoReduceSplit +{ +public: + /** Ctor: must provide amount of reduction, + and whether or not you need to return the eliminated guys + */ + eoLinearRandomSplit(eoHowMany _howMany, bool _returnEliminated = false): + howMany(_howMany), returnEliminated(_returnEliminated) {} + + /** do the job */ + void operator()(eoPop& _newgen, eoPop & _eliminated) + { + unsigned popSize = _newgen.size(); + unsigned eliminated = howMany(popSize); + if (!eliminated) // nothing to do + return ; + unsigned newsize = popSize - eliminated; + if (newsize < 0) + throw std::logic_error("eoLinearRandomSplit: Cannot truncate to a larger size!\n"); + + _eliminated.reserve(_eliminated.size()+eliminated); //in case not empty? + for (unsigned i=0; i::iterator it = _newgen.begin()+loser; + if (returnEliminated) + _eliminated.push_back(*it); + _newgen.erase(it); + } + return ; + } + +private: + eoHowMany howMany; + bool returnEliminated; +}; + + +/** a ReduceSplit class based on a repeated deterministic (reverse!) tournament +To be used in SSGA-like replacements (e.g. see eoSSGADetTournamentReplacement) +*/ +template +class eoDetTournamentTruncateSplit : public eoReduceSplit +{ +public: + /** Ctor: must provide amount of reduction, + and whether or not you need to return the eliminated guys + */ + eoDetTournamentTruncateSplit(unsigned _t_size, eoHowMany _howMany, + bool _returnEliminated = false): + t_size(_t_size), howMany(_howMany), + returnEliminated(_returnEliminated) + { + if (t_size < 2) + { + cout << "Warning, Size for eoDetTournamentTruncateSplit adjusted to 2\n"; + t_size = 2; + } + } + + /** Performs repeated inverse_deterministic_tournament on the pop */ + void operator()(eoPop& _newgen, unsigned _newsize) + { + unsigned popSize = _newgen.size(); + unsigned eliminated = howMany(popSize); + if (!eliminated) // nothing to do + return ; + unsigned newsize = popSize - eliminated; + if (newsize < 0) + throw std::logic_error("eoDetTournamentTruncateSplit: Cannot truncate to a larger size!\n"); + + + _eliminated.reserve(_eliminated.size()+eliminated); //in case not empty? + for (unsigned i=0; i::iterator it = inverse_deterministic_tournament(_newgen.begin(), _newgen.end(), t_size); + if (returnEliminated) + _eliminated.push_back(*it); + _newgen.erase(it); + } + } + +private: + unsigned t_size; + eoHowMany howMany; + bool returnEliminated; +}; + +/** a ReduceSplit class based on a repeated deterministic (reverse!) tournament +To be used in SSGA-like replacements (e.g. see eoSSGAStochTournamentReplacement) +*/ +template +class eoStochTournamentTruncateSplit : public eoReduce +{ +public: + /** Ctor: must provide amount of reduction, + and whether or not you need to return the eliminated guys + */ + eoStochTournamentTruncateSplit(double _t_rate, eoHowMany _howMany, + bool _returnEliminated = false): + t_rate(_t_rate), howMany(_howMany), + returnEliminated(_returnEliminated) + { + if (t_rate <= 0.5) + { + cout << "Warning, Rate for eoStochTournamentTruncateSplit adjusted to 0.51\n"; + t_rate = 0.51; + } + if (t_rate > 1) + { + cout << "Warning, Rate for eoStochTournamentTruncateSplit adjusted to 1\n"; + t_rate = 1; + } + } + + /** Performs repeated inverse_stochastic_tournament on the pop */ + void operator()(eoPop& _newgen, unsigned _newsize) + { + if (!_eliminated.size()) // nothing to do + return; + unsigned oldSize = _newgen.size(); + unsigned newSize = oldSize - _eliminated.size(); + if (newSize < 0) + throw std::logic_error("eoStochTournamentTruncateSplit: Cannot truncate to a larger size!\n"); + + _eliminated.reserve(_eliminated.size()+eliminated); //in case not empty? + for (unsigned i=0; i<_eliminated.size(); i++) + { + eoPop::iterator it = inverse_stochastic_tournament(_newgen.begin(), _newgen.end(), t_rate); + if (returnEliminated) + _eliminated.push_back(*it); + _newgen.erase(it); + } + } + + +private: + double t_rate; + eoHowMany howMany; + bool returnEliminated; +}; + +//----------------------------------------------------------------------------- + +#endif