diff --git a/edo/application/cmaes/main.cpp b/edo/application/cmaes/main.cpp index d1f35941c..97d1d1110 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) @@ -57,26 +57,34 @@ 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 - - eoSelect< EOT >* selector = new eoDetSelect< EOT >( selection_rate ); - state.storeFunctor(selector); - - edoEstimator< Distrib >* estimator = new edoEstimatorNormalMulti< EOT >(); - state.storeFunctor(estimator); - - eoEvalFunc< EOT >* plainEval = new Rosenbrock< EOT >(); - state.storeFunctor(plainEval); + //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 - eoEvalFuncCounterBounder< EOT > eval(*plainEval, max_eval); + + 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 eoRankMuSelect< RealVec >( mu ); + state.storeFunctor(selector); + + edoEstimator< Distrib >* estimator = new edoEstimatorNormalAdaptive( distribution ); + state.storeFunctor(estimator); + + eoEvalFunc< RealVec >* plainEval = new Rosenbrock< RealVec >(); + state.storeFunctor(plainEval); + + 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()) { @@ -129,40 +137,11 @@ 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< EOT >* 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 edoStatNormalMulti< EOT >(); - 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 ); + eoPopLoopEval popEval( eval ); // EDA algorithm configuration - edoAlgo< Distrib >* algo = new edoEDA< Distrib > - (popEval, *selector, *estimator, *sampler, *replacor, + 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 075057186..6e024545b 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 edoAlgoStateless< Distrib > (popEval, *selector, *estimator, *sampler, *replacor, pop_continue, *distribution_continue ); diff --git a/edo/src/edo b/edo/src/edo index 0f7a06377..0da9ed9d4 100644 --- a/edo/src/edo +++ b/edo/src/edo @@ -30,17 +30,21 @@ Authors: #include "edoAlgo.h" //#include "edoEDASA.h" -#include "edoEDA.h" +#include "edoAlgoAdaptive.h" +#include "edoAlgoStateless.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" diff --git a/edo/src/edoAlgo.h b/edo/src/edoAlgo.h index b91a5c2ab..88ed3d63a 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/edoAlgoAdaptive.h similarity index 60% rename from edo/src/edoEDA.h rename to edo/src/edoAlgoAdaptive.h index c0c75be23..dbb8046fc 100644 --- a/edo/src/edoEDA.h +++ b/edo/src/edoAlgoAdaptive.h @@ -22,14 +22,13 @@ Copyright (C) 2010 Thales group /* Authors: Johann Dréo - Caner Candan + Pierre Savéant */ -#ifndef _edoEDA_h -#define _edoEDA_h +#ifndef _edoAlgoAdaptive_h +#define _edoAlgoAdaptive_h #include -//#include #include @@ -41,25 +40,27 @@ Authors: //! edoEDA< D > -template < typename D > -class edoEDA : public edoAlgo< D > +/** A generic stochastic search template for algorithms that need a distribution parameter. + */ +template < typename EOD > +class edoAlgoAdaptive : public edoAlgo< EOD > { public: //! Alias for the type EOT - typedef typename D::EOType EOT; + typedef typename EOD::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: - //! edoEDA constructor /*! 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 @@ -68,15 +69,17 @@ public: \param pop_continuator Stopping criterion based on the population features \param distribution_continuator Stopping criterion based on the distribution features */ - edoEDA ( - eoPopEvalFunc < EOT > & evaluator, - eoSelect< EOT > & selector, - edoEstimator< D > & estimator, - edoSampler< D > & sampler, - eoReplacement< EOT > & replacor, - eoContinue< EOT > & pop_continuator, - edoContinue< D > & distribution_continuator + edoAlgoAdaptive( + 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), @@ -87,10 +90,12 @@ public: _distribution_continuator(distribution_continuator) {} - //! edoEDA constructor without an edoContinue + + //! constructor without an edoContinue /*! 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 @@ -98,14 +103,16 @@ public: \param replacor Replace old solutions by new ones \param pop_continuator Stopping criterion based on the population features */ - edoEDA ( - eoPopEvalFunc < EOT > & evaluator, - eoSelect< EOT > & selector, - edoEstimator< D > & estimator, - edoSampler< D > & sampler, - eoReplacement< EOT > & replacor, - eoContinue< EOT > & pop_continuator + edoAlgoAdaptive ( + EOD & distrib, + eoPopEvalFunc < EOType > & evaluator, + eoSelect< EOType > & selector, + edoEstimator< EOD > & estimator, + edoSampler< EOD > & sampler, + eoReplacement< EOType > & replacor, + eoContinue< EOType > & pop_continuator ) : + _distrib( distrib ), _evaluator(evaluator), _selector(selector), _estimator(estimator), @@ -116,43 +123,40 @@ public: _distribution_continuator( _dummy_continue ) {} - - /** A basic EDA algorithm that iterates over: - * selection, estimation, sampling, bounding, evaluation, replacement + /** Call the algorithm * * \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); + // 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 // The first pop is not supposed to be evaluated (@see eoPopLoopEval). - _evaluator( current_pop, pop ); + // _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); + _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) ); + current_pop.push_back( _sampler(_distrib) ); } // (4) Evaluate new solutions @@ -161,35 +165,40 @@ public: // (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 ) ); + } while( _distribution_continuator( _distrib ) && _pop_continuator( pop ) ); } // operator() -private: + +protected: + + //! The distribution that you want to update + EOD & _distrib; //! A full evaluation function. - eoPopEvalFunc < EOT > & _evaluator; + eoPopEvalFunc & _evaluator; - //! A EOT selector - eoSelect < EOT > & _selector; + //! A EOType selector + eoSelect & _selector; - //! A EOT estimator. It is going to estimate distribution parameters. - edoEstimator< D > & _estimator; + //! A EOType estimator. It is going to estimate distribution parameters. + edoEstimator & _estimator; //! A D sampler - edoSampler< D > & _sampler; + edoSampler & _sampler; - //! A EOT replacor - eoReplacement < EOT > & _replacor; + //! A EOType replacor + eoReplacement & _replacor; - //! A EOT population continuator - eoContinue < EOT > & _pop_continuator; + //! A EOType population continuator + eoContinue & _pop_continuator; //! A D continuator that always return true - edoDummyContinue _dummy_continue; + edoDummyContinue _dummy_continue; //! A D continuator - edoContinue < D > & _distribution_continuator; + edoContinue & _distribution_continuator; }; -#endif // !_edoEDA_h +#endif // !_edoAlgoAdaptive_h + diff --git a/edo/src/edoAlgoStateless.h b/edo/src/edoAlgoStateless.h new file mode 100644 index 000000000..45bcea06f --- /dev/null +++ b/edo/src/edoAlgoStateless.h @@ -0,0 +1,109 @@ +/* +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" + +/** 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 > +{ +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: + + /** 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 + \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 + + You are not supposed to override the tmp_distrib default initalization, or else use edoAlgoAdaptive + */ + 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) + {} + + /** Constructor without an edoContinue + + \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, + 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) + {} + + ~edoAlgoStateless() + { + // delete the temporary distrib allocated in constructors + delete &(this->_distrib); + } +}; + +#endif // !_edoAlgoStateless_h + diff --git a/edo/src/edoEDASA.h b/edo/src/edoEDASA.h index 27ae80620..1966d54db 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 diff --git a/edo/src/edoEstimatorAdaptive.h b/edo/src/edoEstimatorAdaptive.h new file mode 100644 index 000000000..a07f47d1f --- /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 diff --git a/edo/src/edoEstimatorNormalAdaptive.h b/edo/src/edoEstimatorNormalAdaptive.h new file mode 100644 index 000000000..a2566772b --- /dev/null +++ b/edo/src/edoEstimatorNormalAdaptive.h @@ -0,0 +1,249 @@ +/* +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; // column vectors @see edoNormalAdaptive + typedef typename EOD::Matrix Matrix; + + edoEstimatorNormalAdaptive( EOD& distrib ) : + edoEstimatorAdaptive( distrib ), + _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 < 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; + } + +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( N, lambda ); + + // copy the pop (most probably a vector of vectors) in a Eigen3 matrix + 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( lambda ); + assert( weights.size() == lambda ); + + // 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(); + 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))); + + + /********************************************************************** + * WEIGHTED MEAN + *********************************************************************/ + + // compute weighted mean into xmean + Vector xold = 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 ); + + + /********************************************************************** + * 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 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 ); + + + /********************************************************************** + * 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(); + assert( D.innerSize() == N && D.outerSize() == N ); + + // from variance to standard deviations + D.cwiseSqrt(); + d.scaling( D.diagonal() ); + } + + return d; + } // operator() + +protected: + + 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 new file mode 100644 index 000000000..7c6e80a6c --- /dev/null +++ b/edo/src/edoNormalAdaptive.h @@ -0,0 +1,121 @@ + +/* +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 EOT EOType; + typedef typename EOT::AtomType AtomType; + 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 = 1 ) : + _dim(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); + } + + 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 _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; 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 + 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 diff --git a/edo/src/edoNormalMulti.h b/edo/src/edoNormalMulti.h index db36810a0..0c32fad7e 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.innerSize() == _varcovar.innerSize()); + assert(_mean.innerSize() == _varcovar.outerSize()); + } + edoNormalMulti( const Vector & mean, const Matrix & varcovar diff --git a/edo/src/edoSamplerNormalAdaptive.h b/edo/src/edoSamplerNormalAdaptive.h new file mode 100644 index 000000000..e8188105a --- /dev/null +++ b/edo/src/edoSamplerNormalAdaptive.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 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 N = distrib.size(); + assert( N > 0); + + // T = vector of size elements drawn in N(0,1) + Vector T( N ); + for ( unsigned int i = 0; i < N; ++i ) { + T( i ) = rng.normal(); + } + assert(T.innerSize() == N ); + assert(T.outerSize() == 1); + + // 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( N ); + for( unsigned int i = 0; i < N; i++ ) { + solution[i]= sol(i); + } + + return solution; + } +}; +#endif // WITH_EIGEN + +#endif // !_edoSamplerNormalAdaptive_h diff --git a/edo/src/edoSamplerNormalMulti.h b/edo/src/edoSamplerNormalMulti.h index 6420f0408..1f9fe990d 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: diff --git a/edo/src/utils/edoStatNormalMulti.h b/edo/src/utils/edoStatNormalMulti.h index d46e97ef5..961fd7cba 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 diff --git a/eo/NEWS b/eo/NEWS index f4625d6c3..369682af6 100644 --- a/eo/NEWS +++ b/eo/NEWS @@ -1,4 +1,22 @@ * current version + - 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 @@ -20,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 diff --git a/eo/src/apply.h b/eo/src/apply.h index 01256e059..bbd30aa3a 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/eo b/eo/src/eo index 8cebd23a0..3a31daea4 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/eoDetSelect.h b/eo/src/eoDetSelect.h index 4a0858b6a..c89f41f69 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 */ diff --git a/eo/src/eoEvalUserTimeThrowException.h b/eo/src/eoEvalUserTimeThrowException.h index 87e47ac54..2d9ccadd6 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 > { @@ -58,7 +61,7 @@ public: if( current >= _max ) { throw eoMaxTimeException( current ); } else { - func(eo); + this->func(eo); } } } @@ -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) diff --git a/eo/src/eoRankMuSelect.h b/eo/src/eoRankMuSelect.h new file mode 100644 index 000000000..6e0a737ea --- /dev/null +++ b/eo/src/eoRankMuSelect.h @@ -0,0 +1,54 @@ +/* +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 + +#include "eoDetSelect.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