From d03f2abb4667f482bf4a41b9471ed7cae28c0171 Mon Sep 17 00:00:00 2001 From: nojhan Date: Sun, 12 Apr 2020 10:04:46 +0200 Subject: [PATCH] feat: add a new operator: eoAlgoReset - Used in eoAlgoRestart, useful if one wants to reset some things before a restart. - Add operators to reset a pop (EO) and a distrib (EDO) and a wrapper to combine several reset operators. --- edo/src/edoDistribReset.h | 55 ++++++++++++++++ eo/src/eoAlgoReset.h | 130 ++++++++++++++++++++++++++++++++++++++ eo/src/eoAlgoRestart.h | 97 +++++++++++++++++++++++----- 3 files changed, 267 insertions(+), 15 deletions(-) create mode 100644 edo/src/edoDistribReset.h create mode 100644 eo/src/eoAlgoReset.h diff --git a/edo/src/edoDistribReset.h b/edo/src/edoDistribReset.h new file mode 100644 index 000000000..6c4fe118e --- /dev/null +++ b/edo/src/edoDistribReset.h @@ -0,0 +1,55 @@ + +/* +The Evolving Objects framework is a template-based, +ANSI-C++ evolutionary computation library which helps you to write your +own evolutionary algorithms. + +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; +version 2.1 of the License. + +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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Copyright (C) 2020 Thales group +*/ +/* +Authors: + Johann Dréo +*/ + +#ifndef _EDODISTRIBRESET_H_ +#define _EDODISTRIBRESET_H_ + +#include + +/** Reset a distrib when called (as an algorithm). + * + * @ingroup Reset + */ +template +class edoDistribReset : public eoAlgoReset +{ + public: + using EOType = typename D::EOType; + edoDistribReset( D& distrib ) : + _distrib(distrib) + { } + + virtual void operator()( eoPop& pop ) + { + _distrib.reset(); + } + + protected: + D& _distrib; +}; + +#endif // _EDODISTRIBRESET_H_ diff --git a/eo/src/eoAlgoReset.h b/eo/src/eoAlgoReset.h new file mode 100644 index 000000000..ba5f0ffca --- /dev/null +++ b/eo/src/eoAlgoReset.h @@ -0,0 +1,130 @@ +/* +The Evolving Objects framework is a template-based, +ANSI-C++ evolutionary computation library which helps you to write your +own evolutionary algorithms. + +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; +version 2.1 of the License. + +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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Copyright (C) 2020 Thales group +*/ +/* +Authors: + Johann Dréo +*/ + +#ifndef _EOALGORESET_H_ +#define _EOALGORESET_H_ + +#include "eoContinue.h" + +/** @defgroup Reset Algorithms operating a reset of some sort (e.g. on the population). */ + +/** A semantic layer indicating that the derived operator operates a reset of some sort. + * + * @see eoAlgoRestart + * + * @ingroup Algorithms + * @ingroup Reset + */ +template +class eoAlgoReset : public eoAlgo +{ }; + +/** Reset the given population when called. + * + * i.e. Remove all its content, then re-generate individuals + * with the given eoInit. + * + * The reinitialized pop will have either + * the same size than the previous population + * (if no pop_size is passed to the constructor), + * either the previous (given) pop size. + * + * @see eoAlgoRestart + * + * @ingroup Reset + */ +template +class eoAlgoPopReset : public eoAlgoReset +{ + public: + /** Constructor for fixed-size populations. */ + eoAlgoPopReset( eoInit& init, eoPopEvalFunc& pop_eval ) : + _init(init), + _pop_eval(pop_eval), + _has_pop_size(false), + _pop_size(0) + { } + + /** Constructor for resets to the given population size. */ + eoAlgoPopReset( eoInit& init, eoPopEvalFunc& pop_eval, size_t pop_size ) : + _init(init), + _pop_eval(pop_eval), + _has_pop_size(true), + _pop_size(pop_size) + { } + + virtual void operator()(eoPop& pop) + { + if(not _has_pop_size) { + _pop_size = pop.size(); + } + pop.clear(); + pop.append(_pop_size, _init); + _pop_eval(pop,pop); + } + + protected: + eoInit& _init; + eoPopEvalFunc& _pop_eval; + bool _has_pop_size; + size_t _pop_size; +}; + +/** Combine several eoAlgoReset in one. + * + * Useful if you want to perform several different resets. + * + * @ingroup Reset + */ +template +class eoAlgoResetCombine : public eoAlgoReset +{ + public: + eoAlgoResetCombine( eoAlgoReset& reseter ) : + _reseters(1, reseter) + { } + + eoAlgoResetCombine( std::vector*> reseters ) : + _reseters(reseters) + { } + + void add( eoAlgoReset& reseter ) + { + _reseters.push_back(reseter); + } + + virtual void operator()(eoPop& pop) + { + for(auto& reseter : _reseters) { + reseter(pop); + } + } + + protected: + std::vector _reseters; +}; + +#endif // _EOALGORESET_H_ diff --git a/eo/src/eoAlgoRestart.h b/eo/src/eoAlgoRestart.h index 6e98d774a..2f61ea4e5 100644 --- a/eo/src/eoAlgoRestart.h +++ b/eo/src/eoAlgoRestart.h @@ -5,8 +5,8 @@ own evolutionary algorithms. 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.1 of the License, or (at your option) any later version. +License as published by the Free Software Foundation; +version 2.1 of the License. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -17,7 +17,7 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -Copyright (C) 2010 Thales group +Copyright (C) 2020 Thales group */ /* Authors: @@ -29,18 +29,23 @@ Authors: #include "eoPop.h" #include "eoAlgo.h" +#include "eoAlgoReset.h" -/** An algo that restart the given algorithm on a freshly init pop. +/** An algo that restart the given algorithm on a freshly init setting. * - * @note: The fresh population size is set to the size of the last population at previous run. + * If no reseter is specified at construction, + * a reset of the population is performed before each search. + * @see eoAlgoPopReset * - * @ingroup Algorithms + * @ingroup Algorithms */ template class eoAlgoRestart : public eoAlgo { public: /** Constructor with an eoPopEvalFunc + * + * Defaults to using eoAlgoPopReset. * * @param init the initialization operator * @param popeval an evaluator for populations @@ -59,10 +64,14 @@ public: _loop_eval(_dummy_eval), _pop_eval(pop_eval), _algo(algo), - _continue(continuator) + _continue(continuator), + _pop_reset(_init, _pop_eval), + _reseter(_pop_reset) {} /** Constructor with an eoEvalFunc + * + * Defaults to using eoAlgoPopReset. * * @param init the initialization operator * @param popeval an evaluator for populations @@ -81,19 +90,65 @@ public: _loop_eval(_eval), _pop_eval(_loop_eval), _algo(algo), - _continue(continuator) + _continue(continuator), + _pop_reset(_init, _pop_eval), + _reseter(_pop_reset) {} + /** Constructor with an eoPopEvalFunc and an eoAlgoReset + * + * @param popeval an evaluator for populations + * @param algo the algorithm to restart + * @param continuator a stopping criterion to manage the number of restarts + * @param reseter how to reset the search + */ + eoAlgoRestart( + eoPopEvalFunc& pop_eval, + eoAlgo& algo, + eoContinue& continuator, + eoAlgoReset& reseter + ) : + eoAlgo(), + _init(_dummy_init), + _eval(_dummy_eval), + _loop_eval(_dummy_eval), + _pop_eval(pop_eval), + _algo(algo), + _continue(continuator), + _pop_reset(_dummy_init, _pop_eval), + _reseter(reseter) + {} + + /** Constructor with an eoEvalFunc and an eoAlgoReset + * + * @param popeval an evaluator for populations + * @param algo the algorithm to restart + * @param continuator a stopping criterion to manage the number of restarts + * @param reseter how to reset the search + */ + eoAlgoRestart( + eoEvalFunc& eval, + eoAlgo& algo, + eoContinue& continuator, + eoAlgoReset& reseter + ) : + eoAlgo(), + _init(_dummy_init), + _eval(eval), + _loop_eval(_eval), + _pop_eval(_loop_eval), + _algo(algo), + _continue(continuator), + _pop_reset(_dummy_init, _pop_eval), + _reseter(reseter) + {} + + virtual void operator()(eoPop & pop) { do { - size_t pop_size = pop.size(); - pop.clear(); - pop.append(pop_size, _init); - _pop_eval(pop,pop); - + _reseter(pop); _algo(pop); - } while( _continue(pop) ); } @@ -107,6 +162,9 @@ protected: eoAlgo& _algo; eoContinue& _continue; + eoAlgoPopReset _pop_reset; + eoAlgoReset& _reseter; + class eoDummyEval : public eoEvalFunc { public: @@ -114,7 +172,16 @@ protected: {} }; eoDummyEval _dummy_eval; + + class eoDummyInit : public eoInit + { + public: + void operator()(EOT &) + {} + }; + eoDummyInit _dummy_init; + }; - #endif // _EOALGORESTART_H_ +