diff --git a/edo/application/eda/main.cpp b/edo/application/eda/main.cpp index 4208580e..250e6bf1 100644 --- a/edo/application/eda/main.cpp +++ b/edo/application/eda/main.cpp @@ -52,32 +52,19 @@ int main(int ac, char** av) // Letters used by the following declarations: // a d i p t - std::string section("Algorithm parameters"); - - // FIXME: default value to check - //double initial_temperature = parser.createParam((double)10e5, "temperature", "Initial temperature", 'i', section).value(); // i + std::string section("Algorithm parameters"); 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 >(); + edoEstimator< Distrib >* estimator = new edoEstimatorNormalMulti< EOT >(); state.storeFunctor(estimator); - eoSelectOne< EOT >* selectone = new eoDetTournamentSelect< EOT >( 2 ); - state.storeFunctor(selectone); - - edoModifierMass< Distrib >* modifier = new edoNormalMultiCenter< EOT >(); - state.storeFunctor(modifier); - eoEvalFunc< EOT >* plainEval = new Rosenbrock< EOT >(); state.storeFunctor(plainEval); @@ -87,159 +74,65 @@ int main(int ac, char** av) 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 ); state.storeFunctor(init); - //----------------------------------------------------------------------------- - - //----------------------------------------------------------------------------- // (1) Population init and sampler - //----------------------------------------------------------------------------- - // 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 doUniform). - + // 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); - //----------------------------------------------------------------------------- - - - //----------------------------------------------------------------------------- // (2) First evaluation before starting the research algorithm - //----------------------------------------------------------------------------- - apply(eval, pop); - //----------------------------------------------------------------------------- - - - //----------------------------------------------------------------------------- // Prepare bounder class to set bounds of sampling. - // This is used by doSampler. - //----------------------------------------------------------------------------- - - edoBounder< EOT >* bounder = new edoBounderRng< EOT >(EOT(pop[0].size(), -5), - EOT(pop[0].size(), 5), - *gen); + // 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 state.storeFunctor(bounder); - //----------------------------------------------------------------------------- - - - //----------------------------------------------------------------------------- // Prepare sampler class with a specific distribution - //----------------------------------------------------------------------------- - edoSampler< Distrib >* sampler = new edoSamplerNormalMulti< EOT >( *bounder ); state.storeFunctor(sampler); - - //----------------------------------------------------------------------------- - - - //----------------------------------------------------------------------------- - // Metropolis sample parameters - //----------------------------------------------------------------------------- - - //unsigned int popSize = parser.getORcreateParam((unsigned int)20, "popSize", "Population Size", 'P', "Evolution Engine").value(); - - //moContinuator< moDummyNeighbor >* sa_continue = new moIterContinuator< moDummyNeighbor >( popSize ); - //state.storeFunctor(sa_continue); - - //----------------------------------------------------------------------------- - - - //----------------------------------------------------------------------------- - // SA parameters - //----------------------------------------------------------------------------- - - //double threshold_temperature = parser.createParam((double)0.1, "threshold", "Minimal temperature at which stop", 't', section).value(); // t - //double alpha = parser.createParam((double)0.1, "alpha", "Temperature decrease rate", 'a', section).value(); // a - - //moCoolingSchedule* cooling_schedule = new moSimpleCoolingSchedule(initial_temperature, alpha, 0, threshold_temperature); - //state.storeFunctor(cooling_schedule); - - //----------------------------------------------------------------------------- - - - //----------------------------------------------------------------------------- + // stopping criteria // ... and creates the parameter letters: C E g G s T - //----------------------------------------------------------------------------- - eoContinue< EOT >& eo_continue = do_make_continue(parser, state, eval); - - //----------------------------------------------------------------------------- - - - //----------------------------------------------------------------------------- + // population output - //----------------------------------------------------------------------------- - eoCheckPoint< EOT >& pop_continue = do_make_checkpoint(parser, state, eval, eo_continue); - - //----------------------------------------------------------------------------- - - - //----------------------------------------------------------------------------- + // distribution output - //----------------------------------------------------------------------------- - edoDummyContinue< Distrib >* dummy_continue = new edoDummyContinue< Distrib >(); state.storeFunctor(dummy_continue); edoCheckPoint< Distrib >* distribution_continue = new edoCheckPoint< Distrib >( *dummy_continue ); state.storeFunctor(distribution_continue); - //----------------------------------------------------------------------------- - - - //----------------------------------------------------------------------------- // eoEPRemplacement causes the using of the current and previous // sample for sampling. - //----------------------------------------------------------------------------- - eoReplacement< EOT >* replacor = new eoEPReplacement< EOT >(pop.size()); - - // Below, use eoGenerationalReplacement to sample only on the current sample - - //eoReplacement< EOT >* replacor = new eoGenerationalReplacement< EOT >(); // FIXME: to define the size - state.storeFunctor(replacor); - - //----------------------------------------------------------------------------- - - - //----------------------------------------------------------------------------- + // Some stuff to display helper when we are using -h option - //----------------------------------------------------------------------------- - if (parser.userNeedsHelp()) - { - parser.printHelp(std::cout); - exit(1); - } + { + parser.printHelp(std::cout); + exit(1); + } // Help + Verbose routines - make_verbose(parser); make_help(parser); - //----------------------------------------------------------------------------- - - - //----------------------------------------------------------------------------- // population output (after helper) // - // FIXME: theses objects are instanciate there in order to avoid a folder - // removing as doFileSnapshot does within ctor. - //----------------------------------------------------------------------------- - + // 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); @@ -249,13 +142,7 @@ int main(int ac, char** av) fileSnapshot->add(*popStat); pop_continue.add(*fileSnapshot); - //----------------------------------------------------------------------------- - - - //----------------------------------------------------------------------------- // distribution output (after helper) - //----------------------------------------------------------------------------- - edoDistribStat< Distrib >* distrib_stat = new edoStatNormalMulti< EOT >(); state.storeFunctor(distrib_stat); @@ -271,42 +158,24 @@ int main(int ac, char** av) file_monitor->add(*distrib_stat); distribution_continue->add( *file_monitor ); - //----------------------------------------------------------------------------- + eoPopLoopEval popEval( eval ); - - //----------------------------------------------------------------------------- // EDA algorithm configuration - //----------------------------------------------------------------------------- - edoAlgo< Distrib >* algo = new edoEDA< Distrib > - (*selector, *estimator, *selectone, *modifier, *sampler, - pop_continue, *distribution_continue, - eval, - //*sa_continue, *cooling_schedule, initial_temperature, - *replacor); + (*selector, *estimator, *sampler, + pop_continue, *distribution_continue, + popEval, *replacor); - //----------------------------------------------------------------------------- - - - //----------------------------------------------------------------------------- // Beginning of the algorithm call - //----------------------------------------------------------------------------- + try { + do_run(*algo, pop); - try - { - do_run(*algo, pop); - } - catch (eoEvalFuncCounterBounderException& e) - { - eo::log << eo::warnings << "warning: " << e.what() << std::endl; - } - catch (std::exception& e) - { - eo::log << eo::errors << "error: " << e.what() << std::endl; - exit(EXIT_FAILURE); - } - - //----------------------------------------------------------------------------- + } catch (eoEvalFuncCounterBounderException& e) { + eo::log << eo::warnings << "warning: " << e.what() << std::endl; + } catch (std::exception& e) { + eo::log << eo::errors << "error: " << e.what() << std::endl; + exit(EXIT_FAILURE); + } return 0; } diff --git a/edo/src/edoAlgo.h b/edo/src/edoAlgo.h index db0c7fe5..b91a5c2a 100644 --- a/edo/src/edoAlgo.h +++ b/edo/src/edoAlgo.h @@ -31,14 +31,19 @@ Authors: #include -//! edoAlgo< D > - +/** An EDO algorithm difffers from a canonical EO algorithm because it is + * templatized on a Distribution rather than just an EOT. + * + * Derivating from an eoAlgo, it should define an operator()( EOT sol ) + */ template < typename D > class edoAlgo : public eoAlgo< typename D::EOType > { //! Alias for the type typedef typename D::EOType EOT; + // virtual R operator()(A1) = 0; (defined in eoUF) + public: virtual ~edoAlgo(){} }; diff --git a/edo/src/edoEDA.h b/edo/src/edoEDA.h index 51028efc..d70cd27f 100644 --- a/edo/src/edoEDA.h +++ b/edo/src/edoEDA.h @@ -58,179 +58,80 @@ public: //! edoEDA constructor /*! - All the boxes used by a EDASA need to be given. + Takes algo operators, all are mandatory - \param selector Population Selector - \param estimator Distribution Estimator - \param selectone SelectOne - \param modifier Distribution Modifier - \param sampler Distribution Sampler - \param pop_continue Population Continuator - \param distribution_continue Distribution Continuator - \param evaluation Evaluation function. - \param sa_continue Stopping criterion. - \param cooling_schedule Cooling schedule, describes how the temperature is modified. - \param initial_temperature The initial temperature. - \param replacor Population replacor + \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 pop_continuator Stopping criterion based on the population features + \param distribution_continuator Stopping criterion based on the distribution features + \param evaluation Evaluate a population + \param replacor Replace old solutions by new ones */ - edoEDA (eoSelect< EOT > & selector, - edoEstimator< D > & estimator, - eoSelectOne< EOT > & selectone, - edoModifierMass< D > & modifier, - edoSampler< D > & sampler, - eoContinue< EOT > & pop_continue, - edoContinue< D > & distribution_continue, - eoEvalFunc < EOT > & evaluation, - //moContinuator< moDummyNeighbor > & sa_continue, - //moCoolingSchedule & cooling_schedule, - //double initial_temperature, - eoReplacement< EOT > & replacor - ) - : _selector(selector), - _estimator(estimator), - _selectone(selectone), - _modifier(modifier), - _sampler(sampler), - _pop_continue(pop_continue), - _distribution_continue(distribution_continue), - _evaluation(evaluation), - //_sa_continue(sa_continue), - //_cooling_schedule(cooling_schedule), - //_initial_temperature(initial_temperature), - _replacor(replacor) - + edoEDA ( + eoSelect< EOT > & selector, + edoEstimator< D > & estimator, + edoSampler< D > & sampler, + eoContinue< EOT > & pop_continuator, + edoContinue< D > & distribution_continuator, + eoPopEvalFunc < EOT > & evaluator, + eoReplacement< EOT > & replacor + ) + : _selector(selector), + _estimator(estimator), + _sampler(sampler), + _pop_continuator(pop_continuator), + _distribution_continuator(distribution_continuator), + _evaluator(evaluator), + _replacor(replacor) {} - //! function that launches the EDASA algorithm. - /*! - As a moTS or a moHC, the EDASA can be used for HYBRIDATION in an evolutionary algorithm. - - \param pop A population to improve. - \return TRUE. + /** 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< EOT > & pop) { - assert(pop.size() > 0); + assert(pop.size() > 0); - //double temperature = _initial_temperature; + eoPop< EOT > current_pop; + eoPop< EOT > selected_pop; - eoPop< EOT > current_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); - eoPop< EOT > selected_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 ??? - //------------------------------------------------------------- - // Estimating a first time the distribution parameter thanks - // to population. - //------------------------------------------------------------- + // (2) Estimation of the distribution parameters + distrib = _estimator(selected_pop); - D distrib = _estimator(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) ); + } - double size = distrib.size(); - assert(size > 0); + // (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 - - do - { - //------------------------------------------------------------- - // (3) Selection of the best points in the population - //------------------------------------------------------------- - - selected_pop.clear(); - - _selector(pop, selected_pop); - - assert( selected_pop.size() > 0 ); - - //------------------------------------------------------------- - - - //------------------------------------------------------------- - // (4) Estimation of the distribution parameters - //------------------------------------------------------------- - - distrib = _estimator(selected_pop); - - //------------------------------------------------------------- - - - // TODO: utiliser selected_pop ou pop ??? - - assert(selected_pop.size() > 0); - - - //------------------------------------------------------------- - // Init of a variable contening a point with the bestest fitnesses - //------------------------------------------------------------- - - EOT current_solution = _selectone(selected_pop); - - //------------------------------------------------------------- - - - //------------------------------------------------------------- - // Fit the current solution with the distribution parameters (bounds) - //------------------------------------------------------------- - - // FIXME: si besoin de modifier la dispersion de la distribution - // _modifier_dispersion(distribution, selected_pop); - _modifier(distrib, current_solution); - - //------------------------------------------------------------- - - - //------------------------------------------------------------- - // Evaluating a first time the current solution - //------------------------------------------------------------- - - _evaluation( current_solution ); - - //------------------------------------------------------------- - - - //------------------------------------------------------------- - // Building of the sampler in current_pop - //------------------------------------------------------------- - - //_sa_continue.init( current_solution ); - - current_pop.clear(); - - for ( unsigned int i = 0; i < pop.size(); ++i ) - //do - { - EOT candidate_solution = _sampler(distrib); - _evaluation( candidate_solution ); - - // TODO: verifier le critere d'acceptation - if ( candidate_solution.fitness() < current_solution.fitness() - // || rng.uniform() < exp( ::fabs(candidate_solution.fitness() - current_solution.fitness()) / temperature ) - ) - { - current_pop.push_back(candidate_solution); - current_solution = candidate_solution; - } - } - //while ( _sa_continue( current_solution) ); - - //------------------------------------------------------------- - - - _replacor(pop, current_pop); // copy current_pop in pop - - pop.sort(); - - //if ( ! _cooling_schedule( temperature ) ){ eo::log << eo::debug << "_cooling_schedule" << std::endl; break; } - - if ( ! _distribution_continue( distrib ) ){ eo::log << eo::debug << "_distribution_continue" << std::endl; break; } - - if ( ! _pop_continue( pop ) ){ eo::log << eo::debug << "_pop_continue" << std::endl; break; } - - } - while ( 1 ); - } + } while( _distribution_continuator( distrib ) && _pop_continuator( pop ) ); + } // operator() private: @@ -240,32 +141,17 @@ private: //! A EOT estimator. It is going to estimate distribution parameters. edoEstimator< D > & _estimator; - //! SelectOne - eoSelectOne< EOT > & _selectone; - - //! A D modifier - edoModifierMass< D > & _modifier; - //! A D sampler edoSampler< D > & _sampler; //! A EOT population continuator - eoContinue < EOT > & _pop_continue; + eoContinue < EOT > & _pop_continuator; //! A D continuator - edoContinue < D > & _distribution_continue; + edoContinue < D > & _distribution_continuator; //! A full evaluation function. - eoEvalFunc < EOT > & _evaluation; - - //! Stopping criterion before temperature update - //moContinuator< moDummyNeighbor > & _sa_continue; - - //! The cooling schedule - //moCoolingSchedule & _cooling_schedule; - - //! Initial temperature - //double _initial_temperature; + eoPopEvalFunc < EOT > & _evaluator; //! A EOT replacor eoReplacement < EOT > & _replacor;