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.
This commit is contained in:
Johann Dreo 2020-04-12 10:04:46 +02:00
commit d03f2abb46
3 changed files with 267 additions and 15 deletions

55
edo/src/edoDistribReset.h Normal file
View file

@ -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 <johann.dreo@thalesgroup.com>
*/
#ifndef _EDODISTRIBRESET_H_
#define _EDODISTRIBRESET_H_
#include <eoAlgoReset.h>
/** Reset a distrib when called (as an algorithm).
*
* @ingroup Reset
*/
template<class D>
class edoDistribReset : public eoAlgoReset<typename D::EOType>
{
public:
using EOType = typename D::EOType;
edoDistribReset( D& distrib ) :
_distrib(distrib)
{ }
virtual void operator()( eoPop<EOType>& pop )
{
_distrib.reset();
}
protected:
D& _distrib;
};
#endif // _EDODISTRIBRESET_H_

130
eo/src/eoAlgoReset.h Normal file
View file

@ -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 <johann.dreo@thalesgroup.com>
*/
#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 EOT>
class eoAlgoReset : public eoAlgo<EOT>
{ };
/** 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 EOT>
class eoAlgoPopReset : public eoAlgoReset<EOT>
{
public:
/** Constructor for fixed-size populations. */
eoAlgoPopReset( eoInit<EOT>& init, eoPopEvalFunc<EOT>& 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<EOT>& init, eoPopEvalFunc<EOT>& pop_eval, size_t pop_size ) :
_init(init),
_pop_eval(pop_eval),
_has_pop_size(true),
_pop_size(pop_size)
{ }
virtual void operator()(eoPop<EOT>& pop)
{
if(not _has_pop_size) {
_pop_size = pop.size();
}
pop.clear();
pop.append(_pop_size, _init);
_pop_eval(pop,pop);
}
protected:
eoInit<EOT>& _init;
eoPopEvalFunc<EOT>& _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 EOT>
class eoAlgoResetCombine : public eoAlgoReset<EOT>
{
public:
eoAlgoResetCombine( eoAlgoReset<EOT>& reseter ) :
_reseters(1, reseter)
{ }
eoAlgoResetCombine( std::vector<eoAlgoReset<EOT>*> reseters ) :
_reseters(reseters)
{ }
void add( eoAlgoReset<EOT>& reseter )
{
_reseters.push_back(reseter);
}
virtual void operator()(eoPop<EOT>& pop)
{
for(auto& reseter : _reseters) {
reseter(pop);
}
}
protected:
std::vector<EOT*> _reseters;
};
#endif // _EOALGORESET_H_

View file

@ -5,8 +5,8 @@ own evolutionary algorithms.
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License as published by the Free Software Foundation;
version 2.1 of the License, or (at your option) any later version. version 2.1 of the License.
This library is distributed in the hope that it will be useful, This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of 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 License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Copyright (C) 2010 Thales group Copyright (C) 2020 Thales group
*/ */
/* /*
Authors: Authors:
@ -29,18 +29,23 @@ Authors:
#include "eoPop.h" #include "eoPop.h"
#include "eoAlgo.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 EOT> template<class EOT>
class eoAlgoRestart : public eoAlgo<EOT> class eoAlgoRestart : public eoAlgo<EOT>
{ {
public: public:
/** Constructor with an eoPopEvalFunc /** Constructor with an eoPopEvalFunc
*
* Defaults to using eoAlgoPopReset.
* *
* @param init the initialization operator * @param init the initialization operator
* @param popeval an evaluator for populations * @param popeval an evaluator for populations
@ -59,10 +64,14 @@ public:
_loop_eval(_dummy_eval), _loop_eval(_dummy_eval),
_pop_eval(pop_eval), _pop_eval(pop_eval),
_algo(algo), _algo(algo),
_continue(continuator) _continue(continuator),
_pop_reset(_init, _pop_eval),
_reseter(_pop_reset)
{} {}
/** Constructor with an eoEvalFunc /** Constructor with an eoEvalFunc
*
* Defaults to using eoAlgoPopReset.
* *
* @param init the initialization operator * @param init the initialization operator
* @param popeval an evaluator for populations * @param popeval an evaluator for populations
@ -81,19 +90,65 @@ public:
_loop_eval(_eval), _loop_eval(_eval),
_pop_eval(_loop_eval), _pop_eval(_loop_eval),
_algo(algo), _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<EOT>& pop_eval,
eoAlgo<EOT>& algo,
eoContinue<EOT>& continuator,
eoAlgoReset<EOT>& reseter
) :
eoAlgo<EOT>(),
_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<EOT>& eval,
eoAlgo<EOT>& algo,
eoContinue<EOT>& continuator,
eoAlgoReset<EOT>& reseter
) :
eoAlgo<EOT>(),
_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<EOT> & pop) virtual void operator()(eoPop<EOT> & pop)
{ {
do { do {
size_t pop_size = pop.size(); _reseter(pop);
pop.clear();
pop.append(pop_size, _init);
_pop_eval(pop,pop);
_algo(pop); _algo(pop);
} while( _continue(pop) ); } while( _continue(pop) );
} }
@ -107,6 +162,9 @@ protected:
eoAlgo<EOT>& _algo; eoAlgo<EOT>& _algo;
eoContinue<EOT>& _continue; eoContinue<EOT>& _continue;
eoAlgoPopReset<EOT> _pop_reset;
eoAlgoReset<EOT>& _reseter;
class eoDummyEval : public eoEvalFunc<EOT> class eoDummyEval : public eoEvalFunc<EOT>
{ {
public: public:
@ -114,7 +172,16 @@ protected:
{} {}
}; };
eoDummyEval _dummy_eval; eoDummyEval _dummy_eval;
class eoDummyInit : public eoInit<EOT>
{
public:
void operator()(EOT &)
{}
};
eoDummyInit _dummy_init;
}; };
#endif // _EOALGORESTART_H_ #endif // _EOALGORESTART_H_