From 6b5288f195305457be81544e5a4694280dcd5108 Mon Sep 17 00:00:00 2001 From: Johann Dreo Date: Wed, 11 Jul 2012 13:44:43 +0200 Subject: [PATCH 01/24] build with boost by default --- edo/build_gcc_linux_release | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/edo/build_gcc_linux_release b/edo/build_gcc_linux_release index fb220d04..12e06bd0 100755 --- a/edo/build_gcc_linux_release +++ b/edo/build_gcc_linux_release @@ -2,6 +2,6 @@ mkdir -p release cd release -cmake .. +cmake -DWITH_BOOST=1 .. make cd .. From 8f736191c049b484e0f647a31776e232233ae99b Mon Sep 17 00:00:00 2001 From: Johann Dreo Date: Wed, 11 Jul 2012 13:45:56 +0200 Subject: [PATCH 02/24] correct relative include path for edoStatNormalMulti --- edo/src/utils/edoStatNormalMulti.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/edo/src/utils/edoStatNormalMulti.h b/edo/src/utils/edoStatNormalMulti.h index bc5066ac..0de29700 100644 --- a/edo/src/utils/edoStatNormalMulti.h +++ b/edo/src/utils/edoStatNormalMulti.h @@ -31,7 +31,7 @@ Authors: #include #include "edoStat.h" -#include "edoNormalMulti.h" +#include "../edoNormalMulti.h" #ifdef WITH_BOOST From 877937f7fc85b09dcf6ecf8baea0c35724eb8001 Mon Sep 17 00:00:00 2001 From: Johann Dreo Date: Wed, 11 Jul 2012 13:49:23 +0200 Subject: [PATCH 03/24] adaptive distribution for cmaes --- edo/src/edoNormalAdaptive.h | 91 +++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 edo/src/edoNormalAdaptive.h diff --git a/edo/src/edoNormalAdaptive.h b/edo/src/edoNormalAdaptive.h new file mode 100644 index 00000000..499af91f --- /dev/null +++ b/edo/src/edoNormalAdaptive.h @@ -0,0 +1,91 @@ + +/* +The Evolving Distribution Objects framework (EDO) is a template-based, +ANSI-C++ evolutionary computation library which helps you to write your +own estimation of distribution 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. + +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) 2010 Thales group +*/ +/* +Authors: + Johann Dreo + Pierre Savéant +*/ + +#ifndef _edoNormalAdaptive_h +#define _edoNormalAdaptive_h + +#include "edoDistrib.h" + +#ifdef WITH_EIGEN + +#include + +template < typename EOT > +class edoNormalAdaptive : public edoDistrib< EOT > +{ +public: + typedef typename EOT::AtomType AtomType; + typedef Eigen::Matrix< AtomType, Eigen::Dynamic, 1> Vector; + typedef Eigen::Matrix< AtomType, Eigen::Dynamic, Eigen::Dynamic> Matrix; + + edoNormalAdaptive( unsigned int dim ) : + _mean( Vector::Zero(dim) ), + _C( Matrix::Identity(dim,dim) ), + _B( Matrix::Identity(dim,dim) ), + _D( Vector::Constant( dim, 1) ), + _sigma(1.0), + _p_c( Vector::Zero(dim) ), + _p_s( Vector::Zero(dim) ) + { + assert( dim > 0); + } + + unsigned int size() + { + return _mean.innerSize(); + } + + Vector mean() const {return _mean;} + Matrix covar() const {return _covar;} + Matrix coord_sys() const {return _B;} + Vector scaling() const {return _D;} + double sigma() const {return _sigma;} + Vector path_covar() const {return _p_c;} + Vector path_sigma() const {return _p_s;} + + void mean( Vector m ) { _mean = m; } + void covar( Matrix c ) { _C = c; } + void coord_sys( Matrix b ) { _B = b; } + void scaling( Vector d ) { _D = d; } + void sigma( double s ) { _sigma = s; } + void path_covar( Vector p ) { _path_covar = p; } + void path_sigma( Vector p ) { _path_sigma = p; } + +private: + Vector _mean; // + Matrix _C; // covariance matrix + Matrix _B; // eigen vectors / coordinates system + Vector _D; // eigen values / scaling + double _sigma; // + Vector _p_c; // evolution path for C + Vector _p_s; // evolution path for sigma +}; + +#endif // WITH_EIGEN + +#endif // !_edoNormalAdaptive_h From fc66eb4fd77afe9d286f1b3f97ff229cfc6e53fa Mon Sep 17 00:00:00 2001 From: Johann Dreo Date: Wed, 11 Jul 2012 13:49:37 +0200 Subject: [PATCH 04/24] adaptive sampler for cmaes --- edo/src/edoSamplerNormalAdaptive.h | 87 ++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 edo/src/edoSamplerNormalAdaptive.h diff --git a/edo/src/edoSamplerNormalAdaptive.h b/edo/src/edoSamplerNormalAdaptive.h new file mode 100644 index 00000000..193044f0 --- /dev/null +++ b/edo/src/edoSamplerNormalAdaptive.h @@ -0,0 +1,87 @@ +/* +The Evolving Distribution Objects framework (EDO) is a template-based, +ANSI-C++ evolutionary computation library which helps you to write your +own estimation of distribution 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. + +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) 2010 Thales group +*/ +/* +Authors: + Johann Dréo + Pierre Savéant +*/ + +#ifndef _edoSamplerNormalAdaptive_h +#define _edoSamplerNormalAdaptive_h + +#include +#include + +#include + +/** Sample points in a multi-normal law defined by a mean vector and a covariance matrix. + * + * Given M the mean vector and V the covariance matrix, of order n: + * - draw a vector T in N(0,I) (i.e. each value is drawn in a normal law with mean=0 an stddev=1) + * - compute the Cholesky decomposition L of V (i.e. such as V=LL*) + * - return X = M + LT + */ +#ifdef WITH_EIGEN + +template< class EOT, typename EOD = edoNormalAdaptive< EOT > > +class edoSamplerNormalAdaptive : public edoSampler< EOD > +{ +public: + typedef typename EOT::AtomType AtomType; + + typedef typename EOD::Vector Vector; + typedef typename EOD::Matrix Matrix; + + edoSamplerNormalAdaptive( edoRepairer & repairer ) + : edoSampler< EOD >( repairer) + {} + + + EOT sample( EOD& distrib ) + { + unsigned int size = distrib.size(); + assert(size > 0); + + // T = vector of size elements drawn in N(0,1) + Vector T( size ); + for ( unsigned int i = 0; i < size; ++i ) { + T( i ) = rng.normal(); + } + assert(T.innerSize() == size); + assert(T.outerSize() == 1); + + //Vector t_sol = distrib.mean() + distrib.sigma() * distrib.coord_sys() * distrib.scaling() * T; + Vector sol = distrib.mean() + distrib.sigma() + * distrib.coord_sys().dot( distrib.scaling().dot( T ) ); + + // copy in the EOT structure (more probably a vector) + EOT solution( size ); + for( unsigned int i = 0; i < size; i++ ) { + solution[i]= sol(i); + } + + return solution; + } +}; +#endif // WITH_EIGEN + +#endif // !_edoSamplerNormalAdaptive_h From 546f24295ea1249afca51cafe09a5d11c03069f0 Mon Sep 17 00:00:00 2001 From: Johann Dreo Date: Thu, 12 Jul 2012 11:25:07 +0200 Subject: [PATCH 05/24] use adaptive operators to implement CMA-ES --- edo/application/cmaes/main.cpp | 64 +++++++++++++++++++--------------- 1 file changed, 36 insertions(+), 28 deletions(-) diff --git a/edo/application/cmaes/main.cpp b/edo/application/cmaes/main.cpp index 18c3f093..7e73d49d 100644 --- a/edo/application/cmaes/main.cpp +++ b/edo/application/cmaes/main.cpp @@ -41,8 +41,8 @@ Authors: #include "Sphere.h" -typedef eoReal EOT; -typedef edoNormalMulti< EOT > Distrib; +typedef eoReal RealVec; +typedef edoNormalAdaptive< RealVec > Distrib; int main(int ac, char** av) @@ -59,24 +59,32 @@ int main(int ac, char** av) // Instantiate all needed parameters for EDA algorithm double selection_rate = parser.createParam((double)0.5, "selection_rate", "Selection Rate", 'R', section).value(); // R - eoSelect< EOT >* selector = new eoDetSelect< EOT >( selection_rate ); + unsigned long max_eval = parser.getORcreateParam((unsigned long)0, "maxEval", "Maximum number of evaluations (0 = none)", 'E', "Stopping criterion").value(); // E + + unsigned int dim = parser.createParam((unsigned int)10, "dimension-size", "Dimension size", 'd', section).value(); // d + + + double mu = dim / 2; + + + edoNormalAdaptive distribution(dim); + + eoSelect< RealVec >* selector = new eoDetSelect< RealVec >( selection_rate ); state.storeFunctor(selector); - edoEstimator< Distrib >* estimator = new edoEstimatorNormalMulti< EOT >(); + edoEstimator< Distrib >* estimator = new edoEstimatorNormalAdaptive( distribution, mu ); state.storeFunctor(estimator); - eoEvalFunc< EOT >* plainEval = new Rosenbrock< EOT >(); + eoEvalFunc< RealVec >* plainEval = new Rosenbrock< RealVec >(); state.storeFunctor(plainEval); - unsigned long max_eval = parser.getORcreateParam((unsigned long)0, "maxEval", "Maximum number of evaluations (0 = none)", 'E', "Stopping criterion").value(); // E - eoEvalFuncCounterBounder< EOT > eval(*plainEval, max_eval); + eoEvalFuncCounterBounder< RealVec > eval(*plainEval, max_eval); eoRndGenerator< double >* gen = new eoUniformGenerator< double >(-5, 5); state.storeFunctor(gen); - unsigned int dimension_size = parser.createParam((unsigned int)10, "dimension-size", "Dimension size", 'd', section).value(); // d - eoInitFixedLength< EOT >* init = new eoInitFixedLength< EOT >( dimension_size, *gen ); + eoInitFixedLength< RealVec >* init = new eoInitFixedLength< RealVec >( dim, *gen ); state.storeFunctor(init); @@ -84,28 +92,28 @@ int main(int ac, char** av) // Generation of population from do_make_pop (creates parameters, manages persistance and so on...) // ... and creates the parameters: L P r S // this first sampler creates a uniform distribution independently from our distribution (it does not use edoUniform). - eoPop< EOT >& pop = do_make_pop(parser, state, *init); + eoPop< RealVec >& pop = do_make_pop(parser, state, *init); // (2) First evaluation before starting the research algorithm apply(eval, pop); // Prepare bounder class to set bounds of sampling. // This is used by edoSampler. - edoBounder< EOT >* bounder = - new edoBounderRng< EOT >( EOT(pop[0].size(), -5), EOT(pop[0].size(), 5), *gen); // FIXME do not use hard-coded bounds + edoBounder< RealVec >* bounder = + new edoBounderRng< RealVec >( RealVec(dim, -5), RealVec(dim, 5), *gen); // FIXME do not use hard-coded bounds state.storeFunctor(bounder); // Prepare sampler class with a specific distribution - edoSampler< Distrib >* sampler = new edoSamplerNormalMulti< EOT >( *bounder ); + edoSampler< Distrib >* sampler = new edoSamplerNormalAdaptive< RealVec >( *bounder ); state.storeFunctor(sampler); - + // stopping criteria // ... and creates the parameter letters: C E g G s T - eoContinue< EOT >& eo_continue = do_make_continue(parser, state, eval); - + eoContinue< RealVec >& eo_continue = do_make_continue(parser, state, eval); + // population output - eoCheckPoint< EOT >& pop_continue = do_make_checkpoint(parser, state, eval, eo_continue); - + eoCheckPoint< RealVec >& pop_continue = do_make_checkpoint(parser, state, eval, eo_continue); + // distribution output edoDummyContinue< Distrib >* dummy_continue = new edoDummyContinue< Distrib >(); state.storeFunctor(dummy_continue); @@ -115,9 +123,9 @@ int main(int ac, char** av) // eoEPRemplacement causes the using of the current and previous // sample for sampling. - eoReplacement< EOT >* replacor = new eoEPReplacement< EOT >(pop.size()); + eoReplacement< RealVec >* replacor = new eoEPReplacement< RealVec >(pop.size()); state.storeFunctor(replacor); - + // Some stuff to display helper when we are using -h option if (parser.userNeedsHelp()) { @@ -133,7 +141,7 @@ int main(int ac, char** av) // // FIXME: theses objects are instanciated there in order to avoid a folder // removing as edoFileSnapshot does within ctor. - edoPopStat< EOT >* popStat = new edoPopStat; + edoPopStat< RealVec >* popStat = new edoPopStat; state.storeFunctor(popStat); pop_continue.add(*popStat); @@ -143,10 +151,10 @@ int main(int ac, char** av) pop_continue.add(*fileSnapshot); // distribution output (after helper) - edoDistribStat< Distrib >* distrib_stat = new edoStatNormalMulti< EOT >(); - state.storeFunctor(distrib_stat); + // edoDistribStat< Distrib >* distrib_stat = new edoStatNormalAdaptive< RealVec >(); + // state.storeFunctor(distrib_stat); - distribution_continue->add( *distrib_stat ); + // distribution_continue->add( *distrib_stat ); // eoMonitor* stdout_monitor = new eoStdoutMonitor(); // state.storeFunctor(stdout_monitor); @@ -155,14 +163,14 @@ int main(int ac, char** av) eoFileMonitor* file_monitor = new eoFileMonitor("eda_distribution_bounds.txt"); state.storeFunctor(file_monitor); - file_monitor->add(*distrib_stat); + // file_monitor->add(*distrib_stat); distribution_continue->add( *file_monitor ); - eoPopLoopEval popEval( eval ); + eoPopLoopEval popEval( eval ); // EDA algorithm configuration - edoAlgo< Distrib >* algo = new edoEDA< Distrib > - (popEval, *selector, *estimator, *sampler, *replacor, + edoAlgo< Distrib >* algo = new edoCMAES< Distrib > + (distribution, popEval, *selector, *estimator, *sampler, *replacor, pop_continue, *distribution_continue ); From defa972e097fb4fac08c8d9ed9db2d696790e09d Mon Sep 17 00:00:00 2001 From: Johann Dreo Date: Thu, 12 Jul 2012 11:25:34 +0200 Subject: [PATCH 06/24] typedef EOT -> EOType --- edo/src/edoAlgo.h | 2 +- edo/src/edoEDA.h | 44 +++++++++++++++++++-------------------- edo/src/edoEDASA.h | 52 +++++++++++++++++++++++----------------------- 3 files changed, 49 insertions(+), 49 deletions(-) diff --git a/edo/src/edoAlgo.h b/edo/src/edoAlgo.h index b91a5c2a..88ed3d63 100644 --- a/edo/src/edoAlgo.h +++ b/edo/src/edoAlgo.h @@ -40,7 +40,7 @@ template < typename D > class edoAlgo : public eoAlgo< typename D::EOType > { //! Alias for the type - typedef typename D::EOType EOT; + typedef typename D::EOType EOType; // virtual R operator()(A1) = 0; (defined in eoUF) diff --git a/edo/src/edoEDA.h b/edo/src/edoEDA.h index f94e828f..3e02ce64 100644 --- a/edo/src/edoEDA.h +++ b/edo/src/edoEDA.h @@ -46,13 +46,13 @@ class edoEDA : public edoAlgo< D > { public: //! Alias for the type EOT - typedef typename D::EOType EOT; + typedef typename D::EOType EOType; //! Alias for the atom type - typedef typename EOT::AtomType AtomType; + typedef typename EOType::AtomType AtomType; //! Alias for the fitness - typedef typename EOT::Fitness Fitness; + typedef typename EOType::Fitness Fitness; public: @@ -69,12 +69,12 @@ public: \param distribution_continuator Stopping criterion based on the distribution features */ edoEDA ( - eoPopEvalFunc < EOT > & evaluator, - eoSelect< EOT > & selector, + eoPopEvalFunc < EOType > & evaluator, + eoSelect< EOType > & selector, edoEstimator< D > & estimator, edoSampler< D > & sampler, - eoReplacement< EOT > & replacor, - eoContinue< EOT > & pop_continuator, + eoReplacement< EOType > & replacor, + eoContinue< EOType > & pop_continuator, edoContinue< D > & distribution_continuator ) : _evaluator(evaluator), @@ -99,12 +99,12 @@ public: \param pop_continuator Stopping criterion based on the population features */ edoEDA ( - eoPopEvalFunc < EOT > & evaluator, - eoSelect< EOT > & selector, + eoPopEvalFunc < EOType > & evaluator, + eoSelect< EOType > & selector, edoEstimator< D > & estimator, edoSampler< D > & sampler, - eoReplacement< EOT > & replacor, - eoContinue< EOT > & pop_continuator + eoReplacement< EOType > & replacor, + eoContinue< EOType > & pop_continuator ) : _evaluator(evaluator), _selector(selector), @@ -123,12 +123,12 @@ public: * \param pop the population of candidate solutions * \return void */ - void operator ()(eoPop< EOT > & pop) + void operator ()(eoPop< EOType > & pop) { assert(pop.size() > 0); - eoPop< EOT > current_pop; - eoPop< EOT > selected_pop; + eoPop< EOType > current_pop; + eoPop< EOType > selected_pop; // FIXME one must instanciate a first distrib here because there is no empty constructor, see if it is possible to instanciate Distributions without parameters D distrib = _estimator(pop); @@ -167,22 +167,22 @@ public: private: //! A full evaluation function. - eoPopEvalFunc < EOT > & _evaluator; + eoPopEvalFunc < EOType > & _evaluator; - //! A EOT selector - eoSelect < EOT > & _selector; + //! A EOType selector + eoSelect < EOType > & _selector; - //! A EOT estimator. It is going to estimate distribution parameters. + //! A EOType estimator. It is going to estimate distribution parameters. edoEstimator< D > & _estimator; //! A D sampler edoSampler< D > & _sampler; - //! A EOT replacor - eoReplacement < EOT > & _replacor; + //! A EOType replacor + eoReplacement < EOType > & _replacor; - //! A EOT population continuator - eoContinue < EOT > & _pop_continuator; + //! A EOType population continuator + eoContinue < EOType > & _pop_continuator; //! A D continuator that always return true edoDummyContinue _dummy_continue; diff --git a/edo/src/edoEDASA.h b/edo/src/edoEDASA.h index b2f0fe70..82880b3c 100644 --- a/edo/src/edoEDASA.h +++ b/edo/src/edoEDASA.h @@ -46,13 +46,13 @@ class edoEDASA : public edoAlgo< D > { public: //! Alias for the type EOT - typedef typename D::EOType EOT; + typedef typename D::EOType EOType; //! Alias for the atom type - typedef typename EOT::AtomType AtomType; + typedef typename EOType::AtomType AtomType; //! Alias for the fitness - typedef typename EOT::Fitness Fitness; + typedef typename EOType::Fitness Fitness; public: @@ -73,18 +73,18 @@ public: \param initial_temperature The initial temperature. \param replacor Population replacor */ - edoEDASA (eoSelect< EOT > & selector, + edoEDASA (eoSelect< EOType > & selector, edoEstimator< D > & estimator, - eoSelectOne< EOT > & selectone, + eoSelectOne< EOType > & selectone, edoModifierMass< D > & modifier, edoSampler< D > & sampler, - eoContinue< EOT > & pop_continue, + eoContinue< EOType > & pop_continue, edoContinue< D > & distribution_continue, - eoEvalFunc < EOT > & evaluation, - moContinuator< moDummyNeighbor > & sa_continue, - moCoolingSchedule & cooling_schedule, + eoEvalFunc < EOType > & evaluation, + moContinuator< moDummyNeighbor > & sa_continue, + moCoolingSchedule & cooling_schedule, double initial_temperature, - eoReplacement< EOT > & replacor + eoReplacement< EOType > & replacor ) : _selector(selector), _estimator(estimator), @@ -108,15 +108,15 @@ public: \param pop A population to improve. \return TRUE. */ - void operator ()(eoPop< EOT > & pop) + void operator ()(eoPop< EOType > & pop) { assert(pop.size() > 0); double temperature = _initial_temperature; - eoPop< EOT > current_pop; + eoPop< EOType > current_pop; - eoPop< EOT > selected_pop; + eoPop< EOType > selected_pop; //------------------------------------------------------------- @@ -165,7 +165,7 @@ public: // Init of a variable contening a point with the bestest fitnesses //------------------------------------------------------------- - EOT current_solution = _selectone(selected_pop); + EOType current_solution = _selectone(selected_pop); //------------------------------------------------------------- @@ -200,7 +200,7 @@ public: do { - EOT candidate_solution = _sampler(distrib); + EOType candidate_solution = _sampler(distrib); _evaluation( candidate_solution ); // TODO: verifier le critere d'acceptation @@ -232,14 +232,14 @@ public: private: - //! A EOT selector - eoSelect < EOT > & _selector; + //! A EOType selector + eoSelect < EOType > & _selector; - //! A EOT estimator. It is going to estimate distribution parameters. + //! A EOType estimator. It is going to estimate distribution parameters. edoEstimator< D > & _estimator; //! SelectOne - eoSelectOne< EOT > & _selectone; + eoSelectOne< EOType > & _selectone; //! A D modifier edoModifierMass< D > & _modifier; @@ -247,26 +247,26 @@ private: //! A D sampler edoSampler< D > & _sampler; - //! A EOT population continuator - eoContinue < EOT > & _pop_continue; + //! A EOType population continuator + eoContinue < EOType > & _pop_continue; //! A D continuator edoContinue < D > & _distribution_continue; //! A full evaluation function. - eoEvalFunc < EOT > & _evaluation; + eoEvalFunc < EOType > & _evaluation; //! Stopping criterion before temperature update - moContinuator< moDummyNeighbor > & _sa_continue; + moContinuator< moDummyNeighbor > & _sa_continue; //! The cooling schedule - moCoolingSchedule & _cooling_schedule; + moCoolingSchedule & _cooling_schedule; //! Initial temperature double _initial_temperature; - //! A EOT replacor - eoReplacement < EOT > & _replacor; + //! A EOType replacor + eoReplacement < EOType > & _replacor; }; #endif // !_edoEDASA_h From 4b4e6d065c44ade55326e4e307130533e554329b Mon Sep 17 00:00:00 2001 From: Johann Dreo Date: Thu, 12 Jul 2012 11:26:21 +0200 Subject: [PATCH 07/24] include adaptive operators ; deactivate EDASA --- edo/src/edo | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/edo/src/edo b/edo/src/edo index c03acd35..d7506224 100644 --- a/edo/src/edo +++ b/edo/src/edo @@ -29,18 +29,22 @@ Authors: #define _edo_ #include "edoAlgo.h" -#include "edoEDASA.h" +//#include "edoEDASA.h" #include "edoEDA.h" +#include "edoCMAES.h" #include "edoDistrib.h" #include "edoUniform.h" #include "edoNormalMono.h" #include "edoNormalMulti.h" +#include "edoNormalAdaptive.h" #include "edoEstimator.h" #include "edoEstimatorUniform.h" #include "edoEstimatorNormalMono.h" #include "edoEstimatorNormalMulti.h" +#include "edoEstimatorAdaptive.h" +#include "edoEstimatorNormalAdaptive.h" #include "edoModifier.h" #include "edoModifierDispersion.h" @@ -53,6 +57,7 @@ Authors: #include "edoSamplerUniform.h" #include "edoSamplerNormalMono.h" #include "edoSamplerNormalMulti.h" +#include "edoSamplerNormalAdaptive.h" #include "edoVectorBounds.h" From c3e4f13ffd1143690598277ac1794a58857a9377 Mon Sep 17 00:00:00 2001 From: Johann Dreo Date: Thu, 12 Jul 2012 11:27:10 +0200 Subject: [PATCH 08/24] =?UTF-8?q?template<=20class=E2=80=A6=20to=20templat?= =?UTF-8?q?e<=20typename=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- edo/src/edoSamplerNormalMulti.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/edo/src/edoSamplerNormalMulti.h b/edo/src/edoSamplerNormalMulti.h index 6420f040..1f9fe990 100644 --- a/edo/src/edoSamplerNormalMulti.h +++ b/edo/src/edoSamplerNormalMulti.h @@ -47,7 +47,7 @@ Authors: #include #include -template< class EOT, typename EOD = edoNormalMulti< EOT > > +template< typename EOT, typename EOD = edoNormalMulti< EOT > > class edoSamplerNormalMulti : public edoSampler< EOD > { public: @@ -91,7 +91,7 @@ protected: #else #ifdef WITH_EIGEN -template< class EOT, typename EOD = edoNormalMulti< EOT > > +template< typename EOT, typename EOD = edoNormalMulti< EOT > > class edoSamplerNormalMulti : public edoSampler< EOD > { public: From 16f97144b3b7879323ebebd341bf926acc43d751 Mon Sep 17 00:00:00 2001 From: Johann Dreo Date: Thu, 12 Jul 2012 11:27:41 +0200 Subject: [PATCH 09/24] adaptive operators that compiles (but still not work) --- edo/src/edoEstimatorNormalAdaptive.h | 237 +++++++++++++++++++++++++++ edo/src/edoNormalAdaptive.h | 34 +++- edo/src/edoSamplerNormalAdaptive.h | 6 +- 3 files changed, 271 insertions(+), 6 deletions(-) create mode 100644 edo/src/edoEstimatorNormalAdaptive.h diff --git a/edo/src/edoEstimatorNormalAdaptive.h b/edo/src/edoEstimatorNormalAdaptive.h new file mode 100644 index 00000000..0e5a7b02 --- /dev/null +++ b/edo/src/edoEstimatorNormalAdaptive.h @@ -0,0 +1,237 @@ +/* +The Evolving Distribution Objects framework (EDO) is a template-based, +ANSI-C++ evolutionary computation library which helps you to write your +own estimation of distribution 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. + +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) 2010 Thales group +*/ +/* +Authors: + Johann Dréo + Pierre Savéant +*/ + + +#ifndef _edoEstimatorNormalAdaptive_h +#define _edoEstimatorNormalAdaptive_h + +#ifdef WITH_EIGEN + +#include + +#include + +#include "edoNormalAdaptive.h" +#include "edoEstimatorAdaptive.h" + + +//! edoEstimatorNormalMulti< EOT > +template< typename EOT, typename EOD = edoNormalAdaptive > +class edoEstimatorNormalAdaptive : public edoEstimatorAdaptive< EOD > +{ +public: + typedef typename EOT::AtomType AtomType; + typedef typename EOD::Vector Vector; + typedef typename EOD::Matrix Matrix; + + edoEstimatorNormalAdaptive( EOD& distrib, unsigned int mu ) : + edoEstimatorAdaptive( distrib ), + _mu(mu), + _calls(0), + _eigeneval(0) + {} + +private: + Eigen::VectorXd edoCMAESweights( unsigned int pop_size ) + { + // compute recombination weights + Eigen::VectorXd weights( pop_size ); + double sum_w = 0; + for( unsigned int i = 0; i < _mu; ++i ) { + double w_i = log( _mu + 0.5 ) - log( i + 1 ); + weights(i) = w_i; + sum_w += w_i; + } + // normalization of weights + weights /= sum_w; + + return weights; + } + +public: + void resetCalls() + { + _calls = 0; + } + + // update the distribution reference this->distribution() + edoNormalAdaptive operator()( eoPop& pop ) + { + + /********************************************************************** + * INITIALIZATION + *********************************************************************/ + + unsigned int N = pop[0].size(); // FIXME expliciter la dimension du pb ? + unsigned int lambda = pop.size(); + + // number of calls to the operator == number of generations + _calls++; + // number of "evaluations" until now + unsigned int counteval = _calls * lambda; + + // Here, if we are in canonical CMA-ES, + // pop is supposed to be the mu ranked better solutions, + // as the rank mu selection is supposed to have occured. + Matrix arx( pop.size(), N ); + + // copy the pop (most probably a vector of vectors) in a Eigen3 matrix + for( unsigned int i = 0; i < lambda; ++i ) { + for( unsigned int d = 0; d < N; ++d ) { + arx(i,d) = pop[i][d]; + } // dimensions + } // individuals + + // muXone array for weighted recombination + Eigen::VectorXd weights = edoCMAESweights( N ); + + // FIXME exposer les constantes dans l'interface + + // variance-effectiveness of sum w_i x_i + double mueff = pow(weights.sum(), 2) / (weights.array().square()).sum(); + + // time constant for cumulation for C + double cc = (4+mueff/N) / (N+4 + 2*mueff/N); + + // t-const for cumulation for sigma control + double cs = (mueff+2) / (N+mueff+5); + + // learning rate for rank-one update of C + double c1 = 2 / (pow(N+1.3,2)+mueff); + + // and for rank-mu update + double cmu = 2 * (mueff-2+1/mueff) / ( pow(N+2,2)+mueff); + + // damping for sigma + double damps = 1 + 2*std::max(0.0, sqrt((mueff-1)/(N+1))-1) + cs; + + + // shortcut to the referenced distribution + EOD& d = this->distribution(); + + // C^-1/2 + Matrix invsqrtC = + d.coord_sys() * d.scaling().asDiagonal().inverse() + * d.coord_sys().transpose(); + + // expectation of ||N(0,I)|| == norm(randn(N,1)) + double chiN = sqrt(N)*(1-1/(4*N)+1/(21*pow(N,2))); + + + /********************************************************************** + * WEIGHTED MEAN + *********************************************************************/ + + // compute weighted mean into xmean + Vector xold = d.mean(); + d.mean( arx * weights ); + Vector xmean = d.mean(); + + + /********************************************************************** + * CUMULATION: UPDATE EVOLUTION PATHS + *********************************************************************/ + + // cumulation for sigma + d.path_sigma( + (1.0-cs)*d.path_sigma() + sqrt(cs*(2.0-cs)*mueff)*invsqrtC*(xmean-xold)/d.sigma() + ); + + // sign of h + double hsig; + if( d.path_sigma().norm()/sqrt(1.0-pow((1.0-cs),(2.0*counteval/lambda)))/chiN + < 1.4 + 2.0/(N+1.0) + ) { + hsig = 1.0; + } else { + hsig = 0.0; + } + + // cumulation for the covariance matrix + d.path_covar( + (1.0-cc)*d.path_covar() + hsig*sqrt(cc*(2.0-cc)*mueff)*(xmean-xold) / d.sigma() + ); + + Matrix artmp = (1.0/d.sigma()) * arx - xold.rowwise().replicate(_mu); + + + /********************************************************************** + * COVARIANCE MATRIX ADAPTATION + *********************************************************************/ + + d.covar( + (1-c1-cmu) * d.covar() // regard old matrix + + c1 * (d.path_covar()*d.path_covar().transpose() // plus rank one update + + (1-hsig) * cc*(2-cc) * d.covar()) // minor correction if hsig==0 + + cmu * artmp * weights.asDiagonal() * artmp.transpose() // plus rank mu update + ); + + // Adapt step size sigma + d.sigma( d.sigma() * exp((cs/damps)*(d.path_sigma().norm()/chiN - 1)) ); + + + + /********************************************************************** + * DECOMPOSITION OF THE COVARIANCE MATRIX + *********************************************************************/ + + // Decomposition of C into B*diag(D.^2)*B' (diagonalization) + if( counteval - _eigeneval > lambda/(c1+cmu)/N/10 ) { // to achieve O(N^2) + _eigeneval = counteval; + + // enforce symmetry of the covariance matrix + Matrix C = d.covar(); + // FIXME edoEstimatorNormalAdaptive.h:213:44: erreur: expected primary-expression before ‘)’ token + // copy the upper part in the lower one + //C.triangularView() = C.adjoint(); + // Matrix CS = C.triangularView() + C.triangularView().transpose(); + d.covar( C ); + + Eigen::SelfAdjointEigenSolver eigensolver( d.covar() ); // FIXME use JacobiSVD? + d.coord_sys( eigensolver.eigenvectors() ); + Matrix D = eigensolver.eigenvalues().asDiagonal(); + + // from variance to standard deviations + D.cwiseSqrt(); + d.scaling( D ); + } + + return d; + } // operator() + +protected: + + unsigned int _mu; + unsigned int _calls; + unsigned int _eigeneval; + + + // EOD & distribution() inherited from edoEstimatorAdaptive +}; +#endif // WITH_EIGEN + +#endif // !_edoEstimatorNormalAdaptive_h diff --git a/edo/src/edoNormalAdaptive.h b/edo/src/edoNormalAdaptive.h index 499af91f..9ceb6b9f 100644 --- a/edo/src/edoNormalAdaptive.h +++ b/edo/src/edoNormalAdaptive.h @@ -39,6 +39,7 @@ template < typename EOT > class edoNormalAdaptive : public edoDistrib< EOT > { public: + //typedef EOT EOType; typedef typename EOT::AtomType AtomType; typedef Eigen::Matrix< AtomType, Eigen::Dynamic, 1> Vector; typedef Eigen::Matrix< AtomType, Eigen::Dynamic, Eigen::Dynamic> Matrix; @@ -55,13 +56,40 @@ public: assert( dim > 0); } + edoNormalAdaptive( unsigned int dim, + Vector mean, + Matrix C, + Matrix B, + Vector D, + double sigma, + Vector p_c, + Vector p_s + ) : + _mean( mean ), + _C( C ), + _B( B ), + _D( D ), + _sigma(sigma), + _p_c( p_c ), + _p_s( p_s ) + { + assert( dim > 0); + assert( _mean.innerSize() == dim ); + assert( _C.innerSize() == dim && _C.outerSize() == dim ); + assert( _B.innerSize() == dim && _B.outerSize() == dim ); + assert( _D.innerSize() == dim ); + assert( _sigma != 0.0 ); + assert( _p_c.innerSize() == dim ); + assert( _p_s.innerSize() == dim ); + } + unsigned int size() { return _mean.innerSize(); } Vector mean() const {return _mean;} - Matrix covar() const {return _covar;} + Matrix covar() const {return _C;} Matrix coord_sys() const {return _B;} Vector scaling() const {return _D;} double sigma() const {return _sigma;} @@ -73,8 +101,8 @@ public: void coord_sys( Matrix b ) { _B = b; } void scaling( Vector d ) { _D = d; } void sigma( double s ) { _sigma = s; } - void path_covar( Vector p ) { _path_covar = p; } - void path_sigma( Vector p ) { _path_sigma = p; } + void path_covar( Vector p ) { _p_c = p; } + void path_sigma( Vector p ) { _p_s = p; } private: Vector _mean; // diff --git a/edo/src/edoSamplerNormalAdaptive.h b/edo/src/edoSamplerNormalAdaptive.h index 193044f0..edf531ef 100644 --- a/edo/src/edoSamplerNormalAdaptive.h +++ b/edo/src/edoSamplerNormalAdaptive.h @@ -69,9 +69,9 @@ public: assert(T.innerSize() == size); assert(T.outerSize() == 1); - //Vector t_sol = distrib.mean() + distrib.sigma() * distrib.coord_sys() * distrib.scaling() * T; - Vector sol = distrib.mean() + distrib.sigma() - * distrib.coord_sys().dot( distrib.scaling().dot( T ) ); + Vector sol = distrib.mean() + distrib.sigma() * distrib.coord_sys() * (distrib.scaling().dot(T) ); + /*Vector sol = distrib.mean() + distrib.sigma() + * distrib.coord_sys().dot( distrib.scaling().dot( T ) );*/ // copy in the EOT structure (more probably a vector) EOT solution( size ); From 1735660ffe9d61098771048febb978d00c42417a Mon Sep 17 00:00:00 2001 From: Johann Dreo Date: Fri, 13 Jul 2012 14:58:27 +0200 Subject: [PATCH 10/24] use rank mu selector ; bugfix estimator's linear algebra : mu is useless in estimator ; arx = pop^T ; store D as a diagonal ; cwise prod for covar recomposition ; more asserts --- edo/application/cmaes/main.cpp | 6 ++-- edo/src/edoEstimatorNormalAdaptive.h | 52 +++++++++++++++++----------- edo/src/edoNormalAdaptive.h | 30 ++++++++-------- edo/src/edoSamplerNormalAdaptive.h | 20 ++++++----- 4 files changed, 63 insertions(+), 45 deletions(-) diff --git a/edo/application/cmaes/main.cpp b/edo/application/cmaes/main.cpp index 7e73d49d..7a0e73f6 100644 --- a/edo/application/cmaes/main.cpp +++ b/edo/application/cmaes/main.cpp @@ -57,7 +57,7 @@ int main(int ac, char** av) eoState state; // Instantiate all needed parameters for EDA algorithm - double selection_rate = parser.createParam((double)0.5, "selection_rate", "Selection Rate", 'R', section).value(); // R + //double selection_rate = parser.createParam((double)0.5, "selection_rate", "Selection Rate", 'R', section).value(); // R unsigned long max_eval = parser.getORcreateParam((unsigned long)0, "maxEval", "Maximum number of evaluations (0 = none)", 'E', "Stopping criterion").value(); // E @@ -69,10 +69,10 @@ int main(int ac, char** av) edoNormalAdaptive distribution(dim); - eoSelect< RealVec >* selector = new eoDetSelect< RealVec >( selection_rate ); + eoSelect< RealVec >* selector = new eoRankMuSelect< RealVec >( mu ); state.storeFunctor(selector); - edoEstimator< Distrib >* estimator = new edoEstimatorNormalAdaptive( distribution, mu ); + edoEstimator< Distrib >* estimator = new edoEstimatorNormalAdaptive( distribution ); state.storeFunctor(estimator); eoEvalFunc< RealVec >* plainEval = new Rosenbrock< RealVec >(); diff --git a/edo/src/edoEstimatorNormalAdaptive.h b/edo/src/edoEstimatorNormalAdaptive.h index 0e5a7b02..a2566772 100644 --- a/edo/src/edoEstimatorNormalAdaptive.h +++ b/edo/src/edoEstimatorNormalAdaptive.h @@ -45,12 +45,11 @@ class edoEstimatorNormalAdaptive : public edoEstimatorAdaptive< EOD > { public: typedef typename EOT::AtomType AtomType; - typedef typename EOD::Vector Vector; + typedef typename EOD::Vector Vector; // column vectors @see edoNormalAdaptive typedef typename EOD::Matrix Matrix; - edoEstimatorNormalAdaptive( EOD& distrib, unsigned int mu ) : + edoEstimatorNormalAdaptive( EOD& distrib ) : edoEstimatorAdaptive( distrib ), - _mu(mu), _calls(0), _eigeneval(0) {} @@ -61,14 +60,15 @@ private: // compute recombination weights Eigen::VectorXd weights( pop_size ); double sum_w = 0; - for( unsigned int i = 0; i < _mu; ++i ) { - double w_i = log( _mu + 0.5 ) - log( i + 1 ); + for( unsigned int i = 0; i < pop_size; ++i ) { + double w_i = log( pop_size + 0.5 ) - log( i + 1 ); weights(i) = w_i; sum_w += w_i; } // normalization of weights weights /= sum_w; + assert( weights.size() == pop_size); return weights; } @@ -97,17 +97,18 @@ public: // Here, if we are in canonical CMA-ES, // pop is supposed to be the mu ranked better solutions, // as the rank mu selection is supposed to have occured. - Matrix arx( pop.size(), N ); + Matrix arx( N, lambda ); // copy the pop (most probably a vector of vectors) in a Eigen3 matrix - for( unsigned int i = 0; i < lambda; ++i ) { - for( unsigned int d = 0; d < N; ++d ) { - arx(i,d) = pop[i][d]; + for( unsigned int d = 0; d < N; ++d ) { + for( unsigned int i = 0; i < lambda; ++i ) { + arx(d,i) = pop[i][d]; // NOTE: pop = arx.transpose() } // dimensions } // individuals // muXone array for weighted recombination - Eigen::VectorXd weights = edoCMAESweights( N ); + Eigen::VectorXd weights = edoCMAESweights( lambda ); + assert( weights.size() == lambda ); // FIXME exposer les constantes dans l'interface @@ -137,6 +138,8 @@ public: Matrix invsqrtC = d.coord_sys() * d.scaling().asDiagonal().inverse() * d.coord_sys().transpose(); + assert( invsqrtC.innerSize() == d.coord_sys().innerSize() ); + assert( invsqrtC.outerSize() == d.coord_sys().outerSize() ); // expectation of ||N(0,I)|| == norm(randn(N,1)) double chiN = sqrt(N)*(1-1/(4*N)+1/(21*pow(N,2))); @@ -148,8 +151,11 @@ public: // compute weighted mean into xmean Vector xold = d.mean(); - d.mean( arx * weights ); - Vector xmean = d.mean(); + assert( xold.size() == N ); + // xmean ( N, 1 ) = arx( N, lambda ) * weights( lambda, 1 ) + Vector xmean = arx * weights; + assert( xmean.size() == N ); + d.mean( xmean ); /********************************************************************** @@ -157,9 +163,9 @@ public: *********************************************************************/ // cumulation for sigma - d.path_sigma( - (1.0-cs)*d.path_sigma() + sqrt(cs*(2.0-cs)*mueff)*invsqrtC*(xmean-xold)/d.sigma() - ); + d.path_sigma( + (1.0-cs)*d.path_sigma() + sqrt(cs*(2.0-cs)*mueff)*invsqrtC*(xmean-xold)/d.sigma() + ); // sign of h double hsig; @@ -173,10 +179,16 @@ public: // cumulation for the covariance matrix d.path_covar( - (1.0-cc)*d.path_covar() + hsig*sqrt(cc*(2.0-cc)*mueff)*(xmean-xold) / d.sigma() - ); + (1.0-cc)*d.path_covar() + hsig*sqrt(cc*(2.0-cc)*mueff)*(xmean-xold) / d.sigma() + ); - Matrix artmp = (1.0/d.sigma()) * arx - xold.rowwise().replicate(_mu); + Matrix xmu( N, lambda); + xmu = xold.rowwise().replicate(lambda); + assert( xmu.innerSize() == N ); + assert( xmu.outerSize() == lambda ); + Matrix artmp = (1.0/d.sigma()) * (arx - xmu); + // Matrix artmp = (1.0/d.sigma()) * arx - xold.colwise().replicate(lambda); + assert( artmp.innerSize() == N && artmp.outerSize() == lambda ); /********************************************************************** @@ -214,10 +226,11 @@ public: Eigen::SelfAdjointEigenSolver eigensolver( d.covar() ); // FIXME use JacobiSVD? d.coord_sys( eigensolver.eigenvectors() ); Matrix D = eigensolver.eigenvalues().asDiagonal(); + assert( D.innerSize() == N && D.outerSize() == N ); // from variance to standard deviations D.cwiseSqrt(); - d.scaling( D ); + d.scaling( D.diagonal() ); } return d; @@ -225,7 +238,6 @@ public: protected: - unsigned int _mu; unsigned int _calls; unsigned int _eigeneval; diff --git a/edo/src/edoNormalAdaptive.h b/edo/src/edoNormalAdaptive.h index 9ceb6b9f..85db27b5 100644 --- a/edo/src/edoNormalAdaptive.h +++ b/edo/src/edoNormalAdaptive.h @@ -41,10 +41,11 @@ class edoNormalAdaptive : public edoDistrib< EOT > public: //typedef EOT EOType; typedef typename EOT::AtomType AtomType; - typedef Eigen::Matrix< AtomType, Eigen::Dynamic, 1> Vector; + typedef Eigen::Matrix< AtomType, Eigen::Dynamic, 1> Vector; // column vectors ( n lines, 1 column) typedef Eigen::Matrix< AtomType, Eigen::Dynamic, Eigen::Dynamic> Matrix; edoNormalAdaptive( unsigned int dim ) : + _dim(dim), _mean( Vector::Zero(dim) ), _C( Matrix::Identity(dim,dim) ), _B( Matrix::Identity(dim,dim) ), @@ -53,7 +54,7 @@ public: _p_c( Vector::Zero(dim) ), _p_s( Vector::Zero(dim) ) { - assert( dim > 0); + assert( _dim > 0); } edoNormalAdaptive( unsigned int dim, @@ -88,23 +89,24 @@ public: return _mean.innerSize(); } - Vector mean() const {return _mean;} - Matrix covar() const {return _C;} - Matrix coord_sys() const {return _B;} - Vector scaling() const {return _D;} - double sigma() const {return _sigma;} + Vector mean() const {return _mean;} + Matrix covar() const {return _C;} + Matrix coord_sys() const {return _B;} + Vector scaling() const {return _D;} + double sigma() const {return _sigma;} Vector path_covar() const {return _p_c;} Vector path_sigma() const {return _p_s;} - void mean( Vector m ) { _mean = m; } - void covar( Matrix c ) { _C = c; } - void coord_sys( Matrix b ) { _B = b; } - void scaling( Vector d ) { _D = d; } - void sigma( double s ) { _sigma = s; } - void path_covar( Vector p ) { _p_c = p; } - void path_sigma( Vector p ) { _p_s = p; } + void mean( Vector m ) { _mean = m; assert( m.size() == _dim ); } + void covar( Matrix c ) { _C = c; assert( c.innerSize() == _dim && c.outerSize() == _dim ); } + void coord_sys( Matrix b ) { _B = b; assert( b.innerSize() == _dim && b.outerSize() == _dim ); } + void scaling( Vector d ) { _D = d; assert( d.size() == _dim ); } + void sigma( double s ) { _sigma = s; assert( s != 0.0 );} + void path_covar( Vector p ) { _p_c = p; assert( p.size() == _dim ); } + void path_sigma( Vector p ) { _p_s = p; assert( p.size() == _dim ); } private: + unsigned int _dim; Vector _mean; // Matrix _C; // covariance matrix Matrix _B; // eigen vectors / coordinates system diff --git a/edo/src/edoSamplerNormalAdaptive.h b/edo/src/edoSamplerNormalAdaptive.h index edf531ef..e8188105 100644 --- a/edo/src/edoSamplerNormalAdaptive.h +++ b/edo/src/edoSamplerNormalAdaptive.h @@ -58,24 +58,28 @@ public: EOT sample( EOD& distrib ) { - unsigned int size = distrib.size(); - assert(size > 0); + unsigned int N = distrib.size(); + assert( N > 0); // T = vector of size elements drawn in N(0,1) - Vector T( size ); - for ( unsigned int i = 0; i < size; ++i ) { + Vector T( N ); + for ( unsigned int i = 0; i < N; ++i ) { T( i ) = rng.normal(); } - assert(T.innerSize() == size); + assert(T.innerSize() == N ); assert(T.outerSize() == 1); - Vector sol = distrib.mean() + distrib.sigma() * distrib.coord_sys() * (distrib.scaling().dot(T) ); + // mean(N,1) + sigma * B(N,N) * ( D(N,1) .* T(N,1) ) + Vector sol = distrib.mean() + + distrib.sigma() + * distrib.coord_sys() * (distrib.scaling().cwiseProduct(T) ); // C * T = B * (D .* T) + assert( sol.size() == N ); /*Vector sol = distrib.mean() + distrib.sigma() * distrib.coord_sys().dot( distrib.scaling().dot( T ) );*/ // copy in the EOT structure (more probably a vector) - EOT solution( size ); - for( unsigned int i = 0; i < size; i++ ) { + EOT solution( N ); + for( unsigned int i = 0; i < N; i++ ) { solution[i]= sol(i); } From 6cb15cfecffafc53716974dcd87f0e8b4bc1a116 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Jean=20David=20Arjanen?= Date: Mon, 16 Jul 2012 14:18:22 +0200 Subject: [PATCH 11/24] bugfix: Windows compatibility of 'apply' and 'eoEvalUserTimeThrowException' --- eo/NEWS | 1 + eo/src/apply.h | 12 ++++++ eo/src/eoEvalUserTimeThrowException.h | 59 ++++++++++++++++++++++----- 3 files changed, 62 insertions(+), 10 deletions(-) diff --git a/eo/NEWS b/eo/NEWS index f4625d6c..28b25cb4 100644 --- a/eo/NEWS +++ b/eo/NEWS @@ -1,4 +1,5 @@ * current version + - fixed compilation issues in Microsoft Visual C++ * release 1.2 (16. May. 2011) - fixed the incremental allocation issue in variation operators which were diff --git a/eo/src/apply.h b/eo/src/apply.h index 01256e05..bbd30aa3 100644 --- a/eo/src/apply.h +++ b/eo/src/apply.h @@ -58,14 +58,26 @@ void apply(eoUF& _proc, std::vector& _pop) if (!eo::parallel.isDynamic()) { #pragma omp parallel for if(eo::parallel.isEnabled()) //default(none) shared(_proc, _pop, size) +#ifdef _MSC_VER + //Visual Studio supports only OpenMP version 2.0 in which + //an index variable must be of a signed integral type + for (long long i = 0; i < size; ++i) { _proc(_pop[i]); } +#else // _MSC_VER for (size_t i = 0; i < size; ++i) { _proc(_pop[i]); } +#endif } else { #pragma omp parallel for schedule(dynamic) if(eo::parallel.isEnabled()) +#ifdef _MSC_VER + //Visual Studio supports only OpenMP version 2.0 in which + //an index variable must be of a signed integral type + for (long long i = 0; i < size; ++i) { _proc(_pop[i]); } +#else // _MSC_VER //doesnot work with gcc 4.1.2 //default(none) shared(_proc, _pop, size) for (size_t i = 0; i < size; ++i) { _proc(_pop[i]); } +#endif } if ( eo::parallel.enableResults() ) diff --git a/eo/src/eoEvalUserTimeThrowException.h b/eo/src/eoEvalUserTimeThrowException.h index 87e47ac5..f24a246a 100644 --- a/eo/src/eoEvalUserTimeThrowException.h +++ b/eo/src/eoEvalUserTimeThrowException.h @@ -21,27 +21,30 @@ Authors: Johann Dréo */ -#ifndef __unix__ -#warning "Warning: class 'eoEvalUserTimeThrowException' is only available under UNIX systems (defining 'rusage' in 'sys/resource.h'), contributions for other systems are welcomed." -#else +#if !defined(__unix__) && !defined(_WINDOWS) +#warning "Warning: class 'eoEvalUserTimeThrowException' is only available under UNIX (defining 'rusage' in 'sys/resource.h') or Win32 (defining 'GetProcessTimes' in 'WinBase.h') systems, contributions for other systems are welcomed." +#else //!defined(__unix__) && !defined(_WINDOWS) #ifndef __EOEVALUSERTIMETHROWEXCEPTION_H__ #define __EOEVALUSERTIMETHROWEXCEPTION_H__ -#include -#include - -#include - /** Check at each evaluation if a given CPU user time contract has been reached. * * Throw an eoMaxTimeException if the given max time has been reached. * Usefull if you want to end the search independently of generations. - * This class uses (almost-)POSIX headers. + * This class uses (almost-)POSIX or Win32 headers, depending on the platform. * It uses a computation of the user time used on the CPU. For a wallclock time measure, see eoEvalTimeThrowException * * @ingroup Evaluation */ + +#include + +#ifdef __unix__ + +#include +#include + template< class EOT > class eoEvalUserTimeThrowException : public eoEvalFuncCounter< EOT > { @@ -68,5 +71,41 @@ protected: struct rusage _usage; }; +#else +#ifdef _WINDOWS +//here _WINDOWS is defined + +#include + +template< class EOT > +class eoEvalUserTimeThrowException : public eoEvalFuncCounter< EOT > +{ +public: + eoEvalUserTimeThrowException( eoEvalFunc & func, const long max ) : eoEvalFuncCounter( func, "CPU-user"), _max(max) {} + + virtual void operator() ( EOT & eo ) + { + if( eo.invalid() ) { + FILETIME dummy; + GetProcessTimes(GetCurrentProcess(), &dummy, &dummy, &dummy, &_usage); + + ULARGE_INTEGER current; + current.LowPart = _usage.dwLowDateTime; + current.HighPart = _usage.dwHighDateTime; + if( current.QuadPart >= _max ) { + throw eoMaxTimeException( current.QuadPart ); + } else { + func(eo); + } + } + } + +protected: + const long _max; + FILETIME _usage; +}; + +#endif // _WINDOWS +#endif //__unix__ #endif // __EOEVALUSERTIMETHROWEXCEPTION_H__ -#endif // __UNIX__ +#endif //!defined(__unix__) && !defined(_WINDOWS) From 018107544b67ca9ddb4e6e88e4fbc11772835108 Mon Sep 17 00:00:00 2001 From: Johann Dreo Date: Mon, 16 Jul 2012 14:46:27 +0200 Subject: [PATCH 12/24] update the NEWS --- eo/NEWS | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/eo/NEWS b/eo/NEWS index 28b25cb4..369682af 100644 --- a/eo/NEWS +++ b/eo/NEWS @@ -1,5 +1,22 @@ * current version - - fixed compilation issues in Microsoft Visual C++ + - features: + - delete the deprecated code parts (was marked as deprecated in the release 1.1) + - eoSignal: a class to handle signal with eoCheckpoint instances + - eoDetSingleBitFlip: bit flip mutation that changes exactly k bits while checking for duplicate + - eoFunctorStat: a wrapper to turn any stand-alone function and into an eoStat + - generilazed the output of an eoState: now you can change the format, comes with defaults formatting (latex and json) + - eoWrongParamTypeException: a new exception to handle cases where a wrong template is given to eoParser::valueOf + - added a getParam method to the eoParser, that raise an exception if the parameter has not been declared + - eoParserLogger features are now included in the default eoParser + - build system: + - improvements of the build architecture + - create PKGBUILD file for archlinux package manager + - a FindEO module for CMake + - bugfixes: + - fixed regression with gcc 4.7 + - fixed compilation issues in Microsoft Visual C++, related to time measurement + - added several asserts accross the framework (note: asserts are included only in debug mode) + - lot of small bugfixes :-) * release 1.2 (16. May. 2011) - fixed the incremental allocation issue in variation operators which were @@ -21,11 +38,11 @@ - GCC 4.3 compatibility - new versatile log system with several nested verbose levels - classes using intern verbose parameters marked as deprecated, please update your code accordingly if you use one of the following files: - eo/src/eoCombinedInit.h - eo/src/eoGenContinue.h - eo/src/eoProportionalCombinedOp.h - eo/src/utils/eoData.h - eo/src/utils/eoStdoutMonitor.h + eo/src/eoCombinedInit.h + eo/src/eoGenContinue.h + eo/src/eoProportionalCombinedOp.h + eo/src/utils/eoData.h + eo/src/utils/eoStdoutMonitor.h - an evaluator that throw an exception if a maximum eval numbers has been reached, independently of the number of generations - new monitor that can write on any ostream - new continuator that can catch POSIX system user signals From 3cdde2498c7ce74dc4b418aca7a59a3311ebd452 Mon Sep 17 00:00:00 2001 From: Caner Candan Date: Tue, 17 Jul 2012 11:42:49 +0200 Subject: [PATCH 13/24] * eoEvalUserTimeThrowException.h: gcc regression fixed --- eo/src/eoEvalUserTimeThrowException.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eo/src/eoEvalUserTimeThrowException.h b/eo/src/eoEvalUserTimeThrowException.h index 87e47ac5..ed0145de 100644 --- a/eo/src/eoEvalUserTimeThrowException.h +++ b/eo/src/eoEvalUserTimeThrowException.h @@ -58,7 +58,7 @@ public: if( current >= _max ) { throw eoMaxTimeException( current ); } else { - func(eo); + this->func(eo); } } } From 1f4a421dbd7017cc5828cb0f02cbe05ada70ba89 Mon Sep 17 00:00:00 2001 From: Johann Dreo Date: Tue, 17 Jul 2012 17:03:40 +0200 Subject: [PATCH 14/24] simpler cmaes demo, without hazardous file dumping --- edo/application/cmaes/main.cpp | 29 ----------------------------- 1 file changed, 29 deletions(-) diff --git a/edo/application/cmaes/main.cpp b/edo/application/cmaes/main.cpp index 7a0e73f6..5572e2c8 100644 --- a/edo/application/cmaes/main.cpp +++ b/edo/application/cmaes/main.cpp @@ -137,35 +137,6 @@ int main(int ac, char** av) make_verbose(parser); make_help(parser); - // population output (after helper) - // - // FIXME: theses objects are instanciated there in order to avoid a folder - // removing as edoFileSnapshot does within ctor. - edoPopStat< RealVec >* popStat = new edoPopStat; - state.storeFunctor(popStat); - pop_continue.add(*popStat); - - edoFileSnapshot* fileSnapshot = new edoFileSnapshot("EDA_ResPop"); - state.storeFunctor(fileSnapshot); - fileSnapshot->add(*popStat); - pop_continue.add(*fileSnapshot); - - // distribution output (after helper) - // edoDistribStat< Distrib >* distrib_stat = new edoStatNormalAdaptive< RealVec >(); - // state.storeFunctor(distrib_stat); - - // distribution_continue->add( *distrib_stat ); - - // eoMonitor* stdout_monitor = new eoStdoutMonitor(); - // state.storeFunctor(stdout_monitor); - // stdout_monitor->add(*distrib_stat); - // distribution_continue->add( *stdout_monitor ); - - eoFileMonitor* file_monitor = new eoFileMonitor("eda_distribution_bounds.txt"); - state.storeFunctor(file_monitor); - // file_monitor->add(*distrib_stat); - distribution_continue->add( *file_monitor ); - eoPopLoopEval popEval( eval ); // EDA algorithm configuration From 25f0ab782b07ed138dec497e8a3877388736f107 Mon Sep 17 00:00:00 2001 From: Johann Dreo Date: Tue, 17 Jul 2012 17:36:11 +0200 Subject: [PATCH 15/24] move rank mu selection in its own file --- eo/src/eo | 1 + eo/src/eoRankMuSelect.h | 52 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 eo/src/eoRankMuSelect.h diff --git a/eo/src/eo b/eo/src/eo index 8cebd23a..3a31daea 100644 --- a/eo/src/eo +++ b/eo/src/eo @@ -102,6 +102,7 @@ #include // Embedding truncation selection #include +#include // the batch selection - from an eoSelectOne #include diff --git a/eo/src/eoRankMuSelect.h b/eo/src/eoRankMuSelect.h new file mode 100644 index 00000000..8c22f124 --- /dev/null +++ b/eo/src/eoRankMuSelect.h @@ -0,0 +1,52 @@ +/* +The Evolving Distribution Objects framework (EDO) is a template-based, +ANSI-C++ evolutionary computation library which helps you to write your +own estimation of distribution 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. + +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) 2012 Thales group +*/ +/* +Authors: + Johann Dréo +*/ + + +#ifndef _eoRankMuSelect_h +#define _eoRankMuSelect_h + +/** Selects the "Mu" bests individuals. + * + * Note: sorts the population before trucating it. + * + * @ingroup Selectors +*/ +template +class eoRankMuSelect : public eoDetSelect +{ +public : + // false, because mu is not a rate + eoRankMuSelect( unsigned int mu ) : eoDetSelect( mu, false ) {} + + void operator()(const eoPop& source, eoPop& dest) + { + eoPop tmp( source ); + tmp.sort(); + eoDetSelect::operator()( tmp, dest ); + } +}; + +#endif // !_eoRankMuselect_h From 782914395bb97d0880b09bf0238d27c72213c8f8 Mon Sep 17 00:00:00 2001 From: Johann Dreo Date: Tue, 17 Jul 2012 17:36:22 +0200 Subject: [PATCH 16/24] small typo --- eo/src/eoDetSelect.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eo/src/eoDetSelect.h b/eo/src/eoDetSelect.h index 4a0858b6..c89f41f6 100644 --- a/eo/src/eoDetSelect.h +++ b/eo/src/eoDetSelect.h @@ -34,7 +34,7 @@ #include //----------------------------------------------------------------------------- -/** eoDetSelect selects many individuals determinisctically +/** eoDetSelect selects many individuals deterministically * * @ingroup Selectors */ From 251c5b94e63671bcdf41b5bc8c11de2088b4b41a Mon Sep 17 00:00:00 2001 From: Johann Dreo Date: Tue, 17 Jul 2012 17:54:25 +0200 Subject: [PATCH 17/24] bugfix include missing header --- eo/src/eoRankMuSelect.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/eo/src/eoRankMuSelect.h b/eo/src/eoRankMuSelect.h index 8c22f124..6e0a737e 100644 --- a/eo/src/eoRankMuSelect.h +++ b/eo/src/eoRankMuSelect.h @@ -28,6 +28,8 @@ Authors: #ifndef _eoRankMuSelect_h #define _eoRankMuSelect_h +#include "eoDetSelect.h" + /** Selects the "Mu" bests individuals. * * Note: sorts the population before trucating it. From 948903ac1872dbba24d375910ae81ba3cf6a0949 Mon Sep 17 00:00:00 2001 From: Johann Dreo Date: Tue, 17 Jul 2012 18:11:16 +0200 Subject: [PATCH 18/24] bugfix: missing files for cmaes, renamed edoCMAES to AdaptiveAlgo for further refactorization --- edo/application/cmaes/main.cpp | 2 +- edo/src/edo | 2 +- edo/src/edoAdaptiveAlgo.h | 201 +++++++++++++++++++++++++++++++++ edo/src/edoEstimatorAdaptive.h | 55 +++++++++ 4 files changed, 258 insertions(+), 2 deletions(-) create mode 100644 edo/src/edoAdaptiveAlgo.h create mode 100644 edo/src/edoEstimatorAdaptive.h diff --git a/edo/application/cmaes/main.cpp b/edo/application/cmaes/main.cpp index 5572e2c8..b6034854 100644 --- a/edo/application/cmaes/main.cpp +++ b/edo/application/cmaes/main.cpp @@ -140,7 +140,7 @@ int main(int ac, char** av) eoPopLoopEval popEval( eval ); // EDA algorithm configuration - edoAlgo< Distrib >* algo = new edoCMAES< Distrib > + edoAlgo< Distrib >* algo = new edoAdaptiveAlgo< Distrib > (distribution, popEval, *selector, *estimator, *sampler, *replacor, pop_continue, *distribution_continue ); diff --git a/edo/src/edo b/edo/src/edo index d7506224..c73dcb0c 100644 --- a/edo/src/edo +++ b/edo/src/edo @@ -31,7 +31,7 @@ Authors: #include "edoAlgo.h" //#include "edoEDASA.h" #include "edoEDA.h" -#include "edoCMAES.h" +#include "edoAdaptiveAlgo.h" #include "edoDistrib.h" #include "edoUniform.h" diff --git a/edo/src/edoAdaptiveAlgo.h b/edo/src/edoAdaptiveAlgo.h new file mode 100644 index 00000000..03f349a9 --- /dev/null +++ b/edo/src/edoAdaptiveAlgo.h @@ -0,0 +1,201 @@ +/* +The Evolving Distribution Objects framework (EDO) is a template-based, +ANSI-C++ evolutionary computation library which helps you to write your +own estimation of distribution 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. + +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) 2010 Thales group +*/ +/* +Authors: + Johann Dréo + Pierre Savéant +*/ + +#ifndef _edoAdaptiveAlgo_h +#define _edoAdaptiveAlgo_h + +#include + +#include + +#include "edoAlgo.h" +#include "edoEstimator.h" +#include "edoModifierMass.h" +#include "edoSampler.h" +#include "edoContinue.h" + +//! edoEDA< D > + +// FIXME factoriser edoAdaptiveAlgo et edoEDA, la seule différence est la référence _distrib ! +template < typename EOD > +class edoAdaptiveAlgo : public edoAlgo< EOD > +{ +public: + //! Alias for the type EOT + typedef typename EOD::EOType EOType; + + //! Alias for the atom type + typedef typename EOType::AtomType AtomType; + + //! Alias for the fitness + typedef typename EOType::Fitness Fitness; + +public: + + /*! + Takes algo operators, all are mandatory + + \param evaluation Evaluate a population + \param selector Selection of the best candidate solutions in the population + \param estimator Estimation of the distribution parameters + \param sampler Generate feasible solutions using the distribution + \param replacor Replace old solutions by new ones + \param pop_continuator Stopping criterion based on the population features + \param distribution_continuator Stopping criterion based on the distribution features + */ + edoAdaptiveAlgo( + EOD & distrib, + eoPopEvalFunc < EOType > & evaluator, + eoSelect< EOType > & selector, + edoEstimator< EOD > & estimator, + edoSampler< EOD > & sampler, + eoReplacement< EOType > & replacor, + eoContinue< EOType > & pop_continuator, + edoContinue< EOD > & distribution_continuator + ) : + _distrib(distrib), + _evaluator(evaluator), + _selector(selector), + _estimator(estimator), + _sampler(sampler), + _replacor(replacor), + _pop_continuator(pop_continuator), + _dummy_continue(), + _distribution_continuator(distribution_continuator) + {} + + //! constructor without an edoContinue + /*! + Takes algo operators, all are mandatory + + \param evaluation Evaluate a population + \param selector Selection of the best candidate solutions in the population + \param estimator Estimation of the distribution parameters + \param sampler Generate feasible solutions using the distribution + \param replacor Replace old solutions by new ones + \param pop_continuator Stopping criterion based on the population features + */ + edoAdaptiveAlgo ( + eoPopEvalFunc < EOType > & evaluator, + eoSelect< EOType > & selector, + edoEstimator< EOD > & estimator, + edoSampler< EOD > & sampler, + eoReplacement< EOType > & replacor, + eoContinue< EOType > & pop_continuator + ) : + _distrib( EOD() ), + _evaluator(evaluator), + _selector(selector), + _estimator(estimator), + _sampler(sampler), + _replacor(replacor), + _pop_continuator(pop_continuator), + _dummy_continue(), + _distribution_continuator( _dummy_continue ) + {} + + + + /** Covariance Matrix Adaptation Evolution Strategies + * + * \param pop the population of candidate solutions + * \return void + */ + void operator ()(eoPop< EOType > & pop) + { + assert(pop.size() > 0); + + eoPop< EOType > current_pop; + eoPop< EOType > selected_pop; + + // FIXME one must instanciate a first distrib here because there is no empty constructor, see if it is possible to instanciate Distributions without parameters + _distrib = _estimator(pop); + + // Evaluating a first time the candidate solutions + // The first pop is not supposed to be evaluated (@see eoPopLoopEval). + // _evaluator( current_pop, pop ); + + do { + // (1) Selection of the best points in the population + //selected_pop.clear(); // FIXME is it necessary to clear? + _selector(pop, selected_pop); + assert( selected_pop.size() > 0 ); + // TODO: utiliser selected_pop ou pop ??? + + // (2) Estimation of the distribution parameters + _distrib = _estimator(selected_pop); + + // (3) sampling + // The sampler produces feasible solutions (@see edoSampler that + // encapsulate an edoBounder) + current_pop.clear(); + for( unsigned int i = 0; i < pop.size(); ++i ) { + current_pop.push_back( _sampler(_distrib) ); + } + + // (4) Evaluate new solutions + _evaluator( pop, current_pop ); + + // (5) Replace old solutions by new ones + _replacor(pop, current_pop); // e.g. copy current_pop in pop + + } while( _distribution_continuator( _distrib ) && _pop_continuator( pop ) ); + } // operator() + + +protected: + + EOD & _distrib; + + //! A full evaluation function. + eoPopEvalFunc & _evaluator; + + //! A EOType selector + eoSelect & _selector; + + //! A EOType estimator. It is going to estimate distribution parameters. + edoEstimator & _estimator; + + //! A D sampler + edoSampler & _sampler; + + //! A EOType replacor + eoReplacement & _replacor; + + //! A EOType population continuator + eoContinue & _pop_continuator; + + //! A D continuator that always return true + edoDummyContinue _dummy_continue; + + //! A D continuator + edoContinue & _distribution_continuator; + +}; + +#endif // !_edoAdaptiveAlgo_h + diff --git a/edo/src/edoEstimatorAdaptive.h b/edo/src/edoEstimatorAdaptive.h new file mode 100644 index 00000000..a07f47d1 --- /dev/null +++ b/edo/src/edoEstimatorAdaptive.h @@ -0,0 +1,55 @@ +/* +The Evolving Distribution Objects framework (EDO) is a template-based, +ANSI-C++ evolutionary computation library which helps you to write your +own estimation of distribution 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. + +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) 2010 Thales group +*/ +/* +Authors: + Johann Dréo + Pierre Savéant +*/ + +#ifndef _edoEstimatorAdaptive_h +#define _edoEstimatorAdaptive_h + +#include +#include + +#include "edoEstimator.h" + +/** An interface that explicits the needs for a permanent distribution + * that will be updated by operators. + */ +template < typename EOD > +class edoEstimatorAdaptive : public edoEstimator +{ +public: + typedef typename EOD::EOType EOType; + + edoEstimatorAdaptive( EOD& distrib ) : _distrib(distrib) {} + + // virtual D operator() ( eoPop< EOT >& )=0 (provided by eoUF< A1, R >) + + EOD & distribution() const { return _distrib; } + +protected: + EOD & _distrib; +}; + +#endif // !_edoEstimatorAdaptive_h From 0f73b7633aee8eae3ec08c509dd303639995e811 Mon Sep 17 00:00:00 2001 From: Johann Dreo Date: Tue, 17 Jul 2012 18:12:30 +0200 Subject: [PATCH 19/24] empty constructors for distributions, that defaults to 1 dimension --- edo/src/edoNormalAdaptive.h | 4 ++-- edo/src/edoNormalMulti.h | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/edo/src/edoNormalAdaptive.h b/edo/src/edoNormalAdaptive.h index 85db27b5..7c6e80a6 100644 --- a/edo/src/edoNormalAdaptive.h +++ b/edo/src/edoNormalAdaptive.h @@ -44,7 +44,7 @@ public: typedef Eigen::Matrix< AtomType, Eigen::Dynamic, 1> Vector; // column vectors ( n lines, 1 column) typedef Eigen::Matrix< AtomType, Eigen::Dynamic, Eigen::Dynamic> Matrix; - edoNormalAdaptive( unsigned int dim ) : + edoNormalAdaptive( unsigned int dim = 1 ) : _dim(dim), _mean( Vector::Zero(dim) ), _C( Matrix::Identity(dim,dim) ), @@ -57,7 +57,7 @@ public: assert( _dim > 0); } - edoNormalAdaptive( unsigned int dim, + edoNormalAdaptive( unsigned int dim, Vector mean, Matrix C, Matrix B, diff --git a/edo/src/edoNormalMulti.h b/edo/src/edoNormalMulti.h index db36810a..2736cd45 100644 --- a/edo/src/edoNormalMulti.h +++ b/edo/src/edoNormalMulti.h @@ -45,6 +45,15 @@ class edoNormalMulti : public edoDistrib< EOT > public: typedef typename EOT::AtomType AtomType; + edoNormalMulti( unsigned int dim = 1 ) : + _mean( const ublas::vector(0,dim) ), + _varcovar( const ublas::identity_matrix(dim) ) + { + assert(_mean.size() > 0); + assert(_mean.size() == _varcovar.size1()); + assert(_mean.size() == _varcovar.size2()); + } + edoNormalMulti ( const ublas::vector< AtomType >& mean, @@ -86,6 +95,15 @@ public: typedef Eigen::Matrix< AtomType, Eigen::Dynamic, 1> Vector; typedef Eigen::Matrix< AtomType, Eigen::Dynamic, Eigen::Dynamic> Matrix; + edoNormalMulti( unsigned int dim = 1 ) : + _mean( Vector::Zero(dim) ), + _varcovar( Matrix::Identity(dim,dim) ) + { + assert(_mean.size() > 0); + assert(_mean.size() == _varcovar.size1()); + assert(_mean.size() == _varcovar.size2()); + } + edoNormalMulti( const Vector & mean, const Matrix & varcovar From 1317f3b25ae0d5ebba2a875b0722d9012dfa20ae Mon Sep 17 00:00:00 2001 From: Johann Dreo Date: Tue, 17 Jul 2012 18:23:22 +0200 Subject: [PATCH 20/24] bugfix: bad assert api to eigen --- edo/src/edoNormalMulti.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/edo/src/edoNormalMulti.h b/edo/src/edoNormalMulti.h index 2736cd45..0c32fad7 100644 --- a/edo/src/edoNormalMulti.h +++ b/edo/src/edoNormalMulti.h @@ -100,8 +100,8 @@ public: _varcovar( Matrix::Identity(dim,dim) ) { assert(_mean.size() > 0); - assert(_mean.size() == _varcovar.size1()); - assert(_mean.size() == _varcovar.size2()); + assert(_mean.innerSize() == _varcovar.innerSize()); + assert(_mean.innerSize() == _varcovar.outerSize()); } edoNormalMulti( From 5e31fa3020e1613e0fe63ec6d5be51302a6b6e71 Mon Sep 17 00:00:00 2001 From: Johann Dreo Date: Tue, 17 Jul 2012 18:24:04 +0200 Subject: [PATCH 21/24] factorize edoEDA into edoAdaptiveAlgo, use it for both EDA and CMAES applications --- edo/application/eda/main.cpp | 2 +- edo/src/edo | 1 - edo/src/edoAdaptiveAlgo.h | 72 ++++++++++++- edo/src/edoEDA.h | 195 ----------------------------------- 4 files changed, 72 insertions(+), 198 deletions(-) delete mode 100644 edo/src/edoEDA.h diff --git a/edo/application/eda/main.cpp b/edo/application/eda/main.cpp index 07505718..f6ce7b86 100644 --- a/edo/application/eda/main.cpp +++ b/edo/application/eda/main.cpp @@ -161,7 +161,7 @@ int main(int ac, char** av) eoPopLoopEval popEval( eval ); // EDA algorithm configuration - edoAlgo< Distrib >* algo = new edoEDA< Distrib > + edoAlgo< Distrib >* algo = new edoAdaptiveAlgo< Distrib > (popEval, *selector, *estimator, *sampler, *replacor, pop_continue, *distribution_continue ); diff --git a/edo/src/edo b/edo/src/edo index c73dcb0c..70aff6eb 100644 --- a/edo/src/edo +++ b/edo/src/edo @@ -30,7 +30,6 @@ Authors: #include "edoAlgo.h" //#include "edoEDASA.h" -#include "edoEDA.h" #include "edoAdaptiveAlgo.h" #include "edoDistrib.h" diff --git a/edo/src/edoAdaptiveAlgo.h b/edo/src/edoAdaptiveAlgo.h index 03f349a9..2951a871 100644 --- a/edo/src/edoAdaptiveAlgo.h +++ b/edo/src/edoAdaptiveAlgo.h @@ -77,6 +77,7 @@ public: eoContinue< EOType > & pop_continuator, edoContinue< EOD > & distribution_continuator ) : + _dummy_distrib(), _distrib(distrib), _evaluator(evaluator), _selector(selector), @@ -88,6 +89,39 @@ public: _distribution_continuator(distribution_continuator) {} + /*! + Without a distribution + + \param evaluation Evaluate a population + \param selector Selection of the best candidate solutions in the population + \param estimator Estimation of the distribution parameters + \param sampler Generate feasible solutions using the distribution + \param replacor Replace old solutions by new ones + \param pop_continuator Stopping criterion based on the population features + \param distribution_continuator Stopping criterion based on the distribution features + */ + edoAdaptiveAlgo( + eoPopEvalFunc < EOType > & evaluator, + eoSelect< EOType > & selector, + edoEstimator< EOD > & estimator, + edoSampler< EOD > & sampler, + eoReplacement< EOType > & replacor, + eoContinue< EOType > & pop_continuator, + edoContinue< EOD > & distribution_continuator + ) : + _dummy_distrib(), + _distrib( _dummy_distrib ), + _evaluator(evaluator), + _selector(selector), + _estimator(estimator), + _sampler(sampler), + _replacor(replacor), + _pop_continuator(pop_continuator), + _dummy_continue(), + _distribution_continuator(distribution_continuator) + {} + + //! constructor without an edoContinue /*! Takes algo operators, all are mandatory @@ -99,6 +133,38 @@ public: \param replacor Replace old solutions by new ones \param pop_continuator Stopping criterion based on the population features */ + edoAdaptiveAlgo ( + EOD & distrib, + eoPopEvalFunc < EOType > & evaluator, + eoSelect< EOType > & selector, + edoEstimator< EOD > & estimator, + edoSampler< EOD > & sampler, + eoReplacement< EOType > & replacor, + eoContinue< EOType > & pop_continuator + ) : + _dummy_distrib(), + _distrib( distrib ), + _evaluator(evaluator), + _selector(selector), + _estimator(estimator), + _sampler(sampler), + _replacor(replacor), + _pop_continuator(pop_continuator), + _dummy_continue(), + _distribution_continuator( _dummy_continue ) + {} + + //! constructor without an edoContinue nor a distribution + /*! + Takes algo operators, all are mandatory + + \param evaluation Evaluate a population + \param selector Selection of the best candidate solutions in the population + \param estimator Estimation of the distribution parameters + \param sampler Generate feasible solutions using the distribution + \param replacor Replace old solutions by new ones + \param pop_continuator Stopping criterion based on the population features + */ edoAdaptiveAlgo ( eoPopEvalFunc < EOType > & evaluator, eoSelect< EOType > & selector, @@ -107,7 +173,8 @@ public: eoReplacement< EOType > & replacor, eoContinue< EOType > & pop_continuator ) : - _distrib( EOD() ), + _dummy_distrib(), + _distrib( _dummy_distrib ), _evaluator(evaluator), _selector(selector), _estimator(estimator), @@ -120,6 +187,7 @@ public: + /** Covariance Matrix Adaptation Evolution Strategies * * \param pop the population of candidate solutions @@ -169,6 +237,8 @@ public: protected: + EOD _dummy_distrib; + EOD & _distrib; //! A full evaluation function. diff --git a/edo/src/edoEDA.h b/edo/src/edoEDA.h deleted file mode 100644 index 3e02ce64..00000000 --- a/edo/src/edoEDA.h +++ /dev/null @@ -1,195 +0,0 @@ -/* -The Evolving Distribution Objects framework (EDO) is a template-based, -ANSI-C++ evolutionary computation library which helps you to write your -own estimation of distribution 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. - -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) 2010 Thales group -*/ -/* -Authors: - Johann Dréo - Caner Candan -*/ - -#ifndef _edoEDA_h -#define _edoEDA_h - -#include -#include - -#include - -#include "edoAlgo.h" -#include "edoEstimator.h" -#include "edoModifierMass.h" -#include "edoSampler.h" -#include "edoContinue.h" - -//! edoEDA< D > - -template < typename D > -class edoEDA : public edoAlgo< D > -{ -public: - //! Alias for the type EOT - typedef typename D::EOType EOType; - - //! Alias for the atom type - typedef typename EOType::AtomType AtomType; - - //! Alias for the fitness - typedef typename EOType::Fitness Fitness; - -public: - - //! edoEDA constructor - /*! - Takes algo operators, all are mandatory - - \param evaluation Evaluate a population - \param selector Selection of the best candidate solutions in the population - \param estimator Estimation of the distribution parameters - \param sampler Generate feasible solutions using the distribution - \param replacor Replace old solutions by new ones - \param pop_continuator Stopping criterion based on the population features - \param distribution_continuator Stopping criterion based on the distribution features - */ - edoEDA ( - eoPopEvalFunc < EOType > & evaluator, - eoSelect< EOType > & selector, - edoEstimator< D > & estimator, - edoSampler< D > & sampler, - eoReplacement< EOType > & replacor, - eoContinue< EOType > & pop_continuator, - edoContinue< D > & distribution_continuator - ) : - _evaluator(evaluator), - _selector(selector), - _estimator(estimator), - _sampler(sampler), - _replacor(replacor), - _pop_continuator(pop_continuator), - _dummy_continue(), - _distribution_continuator(distribution_continuator) - {} - - //! edoEDA constructor without an edoContinue - /*! - Takes algo operators, all are mandatory - - \param evaluation Evaluate a population - \param selector Selection of the best candidate solutions in the population - \param estimator Estimation of the distribution parameters - \param sampler Generate feasible solutions using the distribution - \param replacor Replace old solutions by new ones - \param pop_continuator Stopping criterion based on the population features - */ - edoEDA ( - eoPopEvalFunc < EOType > & evaluator, - eoSelect< EOType > & selector, - edoEstimator< D > & estimator, - edoSampler< D > & sampler, - eoReplacement< EOType > & replacor, - eoContinue< EOType > & pop_continuator - ) : - _evaluator(evaluator), - _selector(selector), - _estimator(estimator), - _sampler(sampler), - _replacor(replacor), - _pop_continuator(pop_continuator), - _dummy_continue(), - _distribution_continuator( _dummy_continue ) - {} - - - /** A basic EDA algorithm that iterates over: - * selection, estimation, sampling, bounding, evaluation, replacement - * - * \param pop the population of candidate solutions - * \return void - */ - void operator ()(eoPop< EOType > & pop) - { - assert(pop.size() > 0); - - eoPop< EOType > current_pop; - eoPop< EOType > selected_pop; - - // FIXME one must instanciate a first distrib here because there is no empty constructor, see if it is possible to instanciate Distributions without parameters - D distrib = _estimator(pop); - - // Evaluating a first time the candidate solutions - // The first pop is not supposed to be evaluated (@see eoPopLoopEval). - _evaluator( current_pop, pop ); - - do { - // (1) Selection of the best points in the population - //selected_pop.clear(); // FIXME is it necessary to clear? - _selector(pop, selected_pop); - assert( selected_pop.size() > 0 ); - // TODO: utiliser selected_pop ou pop ??? - - // (2) Estimation of the distribution parameters - distrib = _estimator(selected_pop); - - // (3) sampling - // The sampler produces feasible solutions (@see edoSampler that - // encapsulate an edoBounder) - current_pop.clear(); - for( unsigned int i = 0; i < pop.size(); ++i ) { - current_pop.push_back( _sampler(distrib) ); - } - - // (4) Evaluate new solutions - _evaluator( pop, current_pop ); - - // (5) Replace old solutions by new ones - _replacor(pop, current_pop); // e.g. copy current_pop in pop - - } while( _distribution_continuator( distrib ) && _pop_continuator( pop ) ); - } // operator() - -private: - - //! A full evaluation function. - eoPopEvalFunc < EOType > & _evaluator; - - //! A EOType selector - eoSelect < EOType > & _selector; - - //! A EOType estimator. It is going to estimate distribution parameters. - edoEstimator< D > & _estimator; - - //! A D sampler - edoSampler< D > & _sampler; - - //! A EOType replacor - eoReplacement < EOType > & _replacor; - - //! A EOType population continuator - eoContinue < EOType > & _pop_continuator; - - //! A D continuator that always return true - edoDummyContinue _dummy_continue; - - //! A D continuator - edoContinue < D > & _distribution_continuator; - -}; - -#endif // !_edoEDA_h From ae1d88f530cd98a0623012ce9b362ba1b947f975 Mon Sep 17 00:00:00 2001 From: Johann Dreo Date: Tue, 17 Jul 2012 18:35:46 +0200 Subject: [PATCH 22/24] remove FIXMEs and write more comments --- edo/src/edoAdaptiveAlgo.h | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/edo/src/edoAdaptiveAlgo.h b/edo/src/edoAdaptiveAlgo.h index 2951a871..c7703962 100644 --- a/edo/src/edoAdaptiveAlgo.h +++ b/edo/src/edoAdaptiveAlgo.h @@ -40,7 +40,8 @@ Authors: //! edoEDA< D > -// FIXME factoriser edoAdaptiveAlgo et edoEDA, la seule différence est la référence _distrib ! +/** A generic stochastic search template for algorithms that need a distribution parameter. + */ template < typename EOD > class edoAdaptiveAlgo : public edoAlgo< EOD > { @@ -59,6 +60,7 @@ public: /*! Takes algo operators, all are mandatory + \param distrib A distribution to use, if you want to update this parameter (e.gMA-ES) instead of replacing it (e.g. an EDA) \param evaluation Evaluate a population \param selector Selection of the best candidate solutions in the population \param estimator Estimation of the distribution parameters @@ -126,6 +128,7 @@ public: /*! Takes algo operators, all are mandatory + \param distrib A distribution to use, if you want to update this parameter (e.gMA-ES) instead of replacing it (e.g. an EDA) \param evaluation Evaluate a population \param selector Selection of the best candidate solutions in the population \param estimator Estimation of the distribution parameters @@ -156,8 +159,6 @@ public: //! constructor without an edoContinue nor a distribution /*! - Takes algo operators, all are mandatory - \param evaluation Evaluate a population \param selector Selection of the best candidate solutions in the population \param estimator Estimation of the distribution parameters @@ -186,9 +187,7 @@ public: {} - - - /** Covariance Matrix Adaptation Evolution Strategies + /** Call the algorithm * * \param pop the population of candidate solutions * \return void @@ -200,7 +199,8 @@ public: eoPop< EOType > current_pop; eoPop< EOType > selected_pop; - // FIXME one must instanciate a first distrib here because there is no empty constructor, see if it is possible to instanciate Distributions without parameters + // update the extern distribution passed to the estimator (cf. CMA-ES) + // OR replace the dummy distribution for estimators that do not need extern distributions (cf. EDA) _distrib = _estimator(pop); // Evaluating a first time the candidate solutions @@ -209,10 +209,8 @@ public: do { // (1) Selection of the best points in the population - //selected_pop.clear(); // FIXME is it necessary to clear? _selector(pop, selected_pop); assert( selected_pop.size() > 0 ); - // TODO: utiliser selected_pop ou pop ??? // (2) Estimation of the distribution parameters _distrib = _estimator(selected_pop); @@ -237,8 +235,14 @@ public: protected: + /** A dummy distribution, for algorithms willing to replace it instead of updating + * + * Thus we can instanciate _distrib on this and replace it at the first iteration with an estimator. + * This is why an edoDistrib must have an empty constructor. + */ EOD _dummy_distrib; + //! The distribution that you want to update EOD & _distrib; //! A full evaluation function. From 8120116c1b85bb7cad4fb2807ea9455b67367b0a Mon Sep 17 00:00:00 2001 From: Johann Dreo Date: Wed, 18 Jul 2012 10:41:17 +0200 Subject: [PATCH 23/24] Factorize algorithms code in a hierarchy of classes CMAES-like algorithm (edoAlgoAdaptive) main loop work on an extern distribution passed as a reference, which is updated at each iteration EDA-like algorithm (edoAlgoStateless) work on an intern distribution, that is replaced at each iteration edoAlgoStateless inherits from edoAlgoAdaptive, and embed a default member on which the work is done. --- edo/application/cmaes/main.cpp | 2 +- edo/application/eda/main.cpp | 2 +- edo/src/edo | 3 +- .../{edoAdaptiveAlgo.h => edoAlgoAdaptive.h} | 83 +----------- edo/src/edoAlgoStateless.h | 126 ++++++++++++++++++ 5 files changed, 136 insertions(+), 80 deletions(-) rename edo/src/{edoAdaptiveAlgo.h => edoAlgoAdaptive.h} (69%) create mode 100644 edo/src/edoAlgoStateless.h diff --git a/edo/application/cmaes/main.cpp b/edo/application/cmaes/main.cpp index b6034854..4da2fdbe 100644 --- a/edo/application/cmaes/main.cpp +++ b/edo/application/cmaes/main.cpp @@ -140,7 +140,7 @@ int main(int ac, char** av) eoPopLoopEval popEval( eval ); // EDA algorithm configuration - edoAlgo< Distrib >* algo = new edoAdaptiveAlgo< Distrib > + edoAlgo< Distrib >* algo = new edoAlgoAdaptive< Distrib > (distribution, popEval, *selector, *estimator, *sampler, *replacor, pop_continue, *distribution_continue ); diff --git a/edo/application/eda/main.cpp b/edo/application/eda/main.cpp index f6ce7b86..6e024545 100644 --- a/edo/application/eda/main.cpp +++ b/edo/application/eda/main.cpp @@ -161,7 +161,7 @@ int main(int ac, char** av) eoPopLoopEval popEval( eval ); // EDA algorithm configuration - edoAlgo< Distrib >* algo = new edoAdaptiveAlgo< Distrib > + edoAlgo< Distrib >* algo = new edoAlgoStateless< Distrib > (popEval, *selector, *estimator, *sampler, *replacor, pop_continue, *distribution_continue ); diff --git a/edo/src/edo b/edo/src/edo index 70aff6eb..0da9ed9d 100644 --- a/edo/src/edo +++ b/edo/src/edo @@ -30,7 +30,8 @@ Authors: #include "edoAlgo.h" //#include "edoEDASA.h" -#include "edoAdaptiveAlgo.h" +#include "edoAlgoAdaptive.h" +#include "edoAlgoStateless.h" #include "edoDistrib.h" #include "edoUniform.h" diff --git a/edo/src/edoAdaptiveAlgo.h b/edo/src/edoAlgoAdaptive.h similarity index 69% rename from edo/src/edoAdaptiveAlgo.h rename to edo/src/edoAlgoAdaptive.h index c7703962..dbb8046f 100644 --- a/edo/src/edoAdaptiveAlgo.h +++ b/edo/src/edoAlgoAdaptive.h @@ -25,8 +25,8 @@ Authors: Pierre Savéant */ -#ifndef _edoAdaptiveAlgo_h -#define _edoAdaptiveAlgo_h +#ifndef _edoAlgoAdaptive_h +#define _edoAlgoAdaptive_h #include @@ -43,7 +43,7 @@ Authors: /** A generic stochastic search template for algorithms that need a distribution parameter. */ template < typename EOD > -class edoAdaptiveAlgo : public edoAlgo< EOD > +class edoAlgoAdaptive : public edoAlgo< EOD > { public: //! Alias for the type EOT @@ -69,7 +69,7 @@ public: \param pop_continuator Stopping criterion based on the population features \param distribution_continuator Stopping criterion based on the distribution features */ - edoAdaptiveAlgo( + edoAlgoAdaptive( EOD & distrib, eoPopEvalFunc < EOType > & evaluator, eoSelect< EOType > & selector, @@ -79,7 +79,6 @@ public: eoContinue< EOType > & pop_continuator, edoContinue< EOD > & distribution_continuator ) : - _dummy_distrib(), _distrib(distrib), _evaluator(evaluator), _selector(selector), @@ -91,38 +90,6 @@ public: _distribution_continuator(distribution_continuator) {} - /*! - Without a distribution - - \param evaluation Evaluate a population - \param selector Selection of the best candidate solutions in the population - \param estimator Estimation of the distribution parameters - \param sampler Generate feasible solutions using the distribution - \param replacor Replace old solutions by new ones - \param pop_continuator Stopping criterion based on the population features - \param distribution_continuator Stopping criterion based on the distribution features - */ - edoAdaptiveAlgo( - eoPopEvalFunc < EOType > & evaluator, - eoSelect< EOType > & selector, - edoEstimator< EOD > & estimator, - edoSampler< EOD > & sampler, - eoReplacement< EOType > & replacor, - eoContinue< EOType > & pop_continuator, - edoContinue< EOD > & distribution_continuator - ) : - _dummy_distrib(), - _distrib( _dummy_distrib ), - _evaluator(evaluator), - _selector(selector), - _estimator(estimator), - _sampler(sampler), - _replacor(replacor), - _pop_continuator(pop_continuator), - _dummy_continue(), - _distribution_continuator(distribution_continuator) - {} - //! constructor without an edoContinue /*! @@ -136,7 +103,7 @@ public: \param replacor Replace old solutions by new ones \param pop_continuator Stopping criterion based on the population features */ - edoAdaptiveAlgo ( + edoAlgoAdaptive ( EOD & distrib, eoPopEvalFunc < EOType > & evaluator, eoSelect< EOType > & selector, @@ -145,7 +112,6 @@ public: eoReplacement< EOType > & replacor, eoContinue< EOType > & pop_continuator ) : - _dummy_distrib(), _distrib( distrib ), _evaluator(evaluator), _selector(selector), @@ -157,36 +123,6 @@ public: _distribution_continuator( _dummy_continue ) {} - //! constructor without an edoContinue nor a distribution - /*! - \param evaluation Evaluate a population - \param selector Selection of the best candidate solutions in the population - \param estimator Estimation of the distribution parameters - \param sampler Generate feasible solutions using the distribution - \param replacor Replace old solutions by new ones - \param pop_continuator Stopping criterion based on the population features - */ - edoAdaptiveAlgo ( - eoPopEvalFunc < EOType > & evaluator, - eoSelect< EOType > & selector, - edoEstimator< EOD > & estimator, - edoSampler< EOD > & sampler, - eoReplacement< EOType > & replacor, - eoContinue< EOType > & pop_continuator - ) : - _dummy_distrib(), - _distrib( _dummy_distrib ), - _evaluator(evaluator), - _selector(selector), - _estimator(estimator), - _sampler(sampler), - _replacor(replacor), - _pop_continuator(pop_continuator), - _dummy_continue(), - _distribution_continuator( _dummy_continue ) - {} - - /** Call the algorithm * * \param pop the population of candidate solutions @@ -235,13 +171,6 @@ public: protected: - /** A dummy distribution, for algorithms willing to replace it instead of updating - * - * Thus we can instanciate _distrib on this and replace it at the first iteration with an estimator. - * This is why an edoDistrib must have an empty constructor. - */ - EOD _dummy_distrib; - //! The distribution that you want to update EOD & _distrib; @@ -271,5 +200,5 @@ protected: }; -#endif // !_edoAdaptiveAlgo_h +#endif // !_edoAlgoAdaptive_h diff --git a/edo/src/edoAlgoStateless.h b/edo/src/edoAlgoStateless.h new file mode 100644 index 00000000..c2d4834d --- /dev/null +++ b/edo/src/edoAlgoStateless.h @@ -0,0 +1,126 @@ +/* +The Evolving Distribution Objects framework (EDO) is a template-based, +ANSI-C++ evolutionary computation library which helps you to write your +own estimation of distribution 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. + +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) 2010 Thales group +*/ +/* +Authors: + Johann Dréo + Pierre Savéant +*/ + +#ifndef _edoAlgoStateless_h +#define _edoAlgoStateless_h + +#include "edoAlgoAdaptive.h" + +//! edoEDA< D > + +/** A generic stochastic search template for algorithms that need a distribution parameter. + */ +template < typename EOD > +class edoAlgoStateless : public edoAlgoAdaptive< EOD > +{ +public: + //! Alias for the type EOT + typedef typename EOD::EOType EOType; + + //! Alias for the atom type + typedef typename EOType::AtomType AtomType; + + //! Alias for the fitness + typedef typename EOType::Fitness Fitness; + +public: + + + /*! + Without a distribution + + \param evaluation Evaluate a population + \param selector Selection of the best candidate solutions in the population + \param estimator Estimation of the distribution parameters + \param sampler Generate feasible solutions using the distribution + \param replacor Replace old solutions by new ones + \param pop_continuator Stopping criterion based on the population features + \param distribution_continuator Stopping criterion based on the distribution features + */ + edoAlgoStateless( + eoPopEvalFunc < EOType > & evaluator, + eoSelect< EOType > & selector, + edoEstimator< EOD > & estimator, + edoSampler< EOD > & sampler, + eoReplacement< EOType > & replacor, + eoContinue< EOType > & pop_continuator, + edoContinue< EOD > & distribution_continuator, + EOD* tmp_distrib = (new EOD()) + ) : + edoAlgoAdaptive( *tmp_distrib, evaluator, selector, estimator, sampler, replacor, pop_continuator, distribution_continuator), + _tmp_distrib( tmp_distrib ), + _dummy_distrib() + { + this->_distrib = _dummy_distrib; + } + + //! constructor without an edoContinue nor a distribution + /*! + \param evaluation Evaluate a population + \param selector Selection of the best candidate solutions in the population + \param estimator Estimation of the distribution parameters + \param sampler Generate feasible solutions using the distribution + \param replacor Replace old solutions by new ones + \param pop_continuator Stopping criterion based on the population features + */ + edoAlgoStateless ( + eoPopEvalFunc < EOType > & evaluator, + eoSelect< EOType > & selector, + edoEstimator< EOD > & estimator, + edoSampler< EOD > & sampler, + eoReplacement< EOType > & replacor, + eoContinue< EOType > & pop_continuator, + EOD* tmp_distrib = (new EOD()) + ) : + edoAlgoAdaptive( *tmp_distrib, evaluator, selector, estimator, sampler, replacor, pop_continuator), + _tmp_distrib( tmp_distrib ), + _dummy_distrib() + { + this->_distrib = _dummy_distrib; + } + + ~edoAlgoStateless() + { + delete _tmp_distrib; + } + + +protected: + + EOD* _tmp_distrib; + + /** A dummy distribution, for algorithms willing to replace it instead of updating + * + * Thus we can instanciate _distrib on this and replace it at the first iteration with an estimator. + * This is why an edoDistrib must have an empty constructor. + */ + EOD _dummy_distrib; + +}; + +#endif // !_edoAlgoStateless_h + From 388358bc5c35f0ab3d7c9c22a729a07e8819f1ca Mon Sep 17 00:00:00 2001 From: Johann Dreo Date: Wed, 18 Jul 2012 11:43:59 +0200 Subject: [PATCH 24/24] get rid of the useless temporary members and directly delete the adress of the referenced distrib --- edo/src/edoAlgoStateless.h | 53 +++++++++++++------------------------- 1 file changed, 18 insertions(+), 35 deletions(-) diff --git a/edo/src/edoAlgoStateless.h b/edo/src/edoAlgoStateless.h index c2d4834d..45bcea06 100644 --- a/edo/src/edoAlgoStateless.h +++ b/edo/src/edoAlgoStateless.h @@ -30,9 +30,11 @@ Authors: #include "edoAlgoAdaptive.h" -//! edoEDA< D > - -/** A generic stochastic search template for algorithms that need a distribution parameter. +/** A generic stochastic search template for algorithms that need a distribution parameter but replace it rather than update it + * + * This use a default dummy distribution, for algorithms willing to replace it instead of updating + * Thus we can instanciate _distrib on this and replace it at the first iteration with an estimator. + * This is why an edoDistrib must have an empty constructor. */ template < typename EOD > class edoAlgoStateless : public edoAlgoAdaptive< EOD > @@ -49,10 +51,7 @@ public: public: - - /*! - Without a distribution - + /** Full constructor \param evaluation Evaluate a population \param selector Selection of the best candidate solutions in the population \param estimator Estimation of the distribution parameters @@ -60,6 +59,8 @@ public: \param replacor Replace old solutions by new ones \param pop_continuator Stopping criterion based on the population features \param distribution_continuator Stopping criterion based on the distribution features + + You are not supposed to override the tmp_distrib default initalization, or else use edoAlgoAdaptive */ edoAlgoStateless( eoPopEvalFunc < EOType > & evaluator, @@ -71,21 +72,19 @@ public: edoContinue< EOD > & distribution_continuator, EOD* tmp_distrib = (new EOD()) ) : - edoAlgoAdaptive( *tmp_distrib, evaluator, selector, estimator, sampler, replacor, pop_continuator, distribution_continuator), - _tmp_distrib( tmp_distrib ), - _dummy_distrib() - { - this->_distrib = _dummy_distrib; - } + edoAlgoAdaptive( *tmp_distrib, evaluator, selector, estimator, sampler, replacor, pop_continuator, distribution_continuator) + {} + + /** Constructor without an edoContinue - //! constructor without an edoContinue nor a distribution - /*! \param evaluation Evaluate a population \param selector Selection of the best candidate solutions in the population \param estimator Estimation of the distribution parameters \param sampler Generate feasible solutions using the distribution \param replacor Replace old solutions by new ones \param pop_continuator Stopping criterion based on the population features + + You are not supposed to override the tmp_distrib default initalization, or else use edoAlgoAdaptive */ edoAlgoStateless ( eoPopEvalFunc < EOType > & evaluator, @@ -96,30 +95,14 @@ public: eoContinue< EOType > & pop_continuator, EOD* tmp_distrib = (new EOD()) ) : - edoAlgoAdaptive( *tmp_distrib, evaluator, selector, estimator, sampler, replacor, pop_continuator), - _tmp_distrib( tmp_distrib ), - _dummy_distrib() - { - this->_distrib = _dummy_distrib; - } + edoAlgoAdaptive( *tmp_distrib, evaluator, selector, estimator, sampler, replacor, pop_continuator) + {} ~edoAlgoStateless() { - delete _tmp_distrib; + // delete the temporary distrib allocated in constructors + delete &(this->_distrib); } - - -protected: - - EOD* _tmp_distrib; - - /** A dummy distribution, for algorithms willing to replace it instead of updating - * - * Thus we can instanciate _distrib on this and replace it at the first iteration with an estimator. - * This is why an edoDistrib must have an empty constructor. - */ - EOD _dummy_distrib; - }; #endif // !_edoAlgoStateless_h