update the edoEDA to a simple EDA

This commit is contained in:
nojhan 2011-09-13 16:53:30 +02:00
commit c63e5f919f
3 changed files with 98 additions and 338 deletions

View file

@ -52,32 +52,19 @@ int main(int ac, char** av)
// Letters used by the following declarations: // Letters used by the following declarations:
// a d i p t // a d i p t
std::string section("Algorithm parameters"); std::string section("Algorithm parameters");
// FIXME: default value to check
//double initial_temperature = parser.createParam((double)10e5, "temperature", "Initial temperature", 'i', section).value(); // i
eoState state; eoState state;
//-----------------------------------------------------------------------------
// Instantiate all needed parameters for EDA algorithm // 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
eoSelect< EOT >* selector = new eoDetSelect< EOT >( selection_rate ); eoSelect< EOT >* selector = new eoDetSelect< EOT >( selection_rate );
state.storeFunctor(selector); state.storeFunctor(selector);
edoEstimator< Distrib >* estimator = new edoEstimatorNormalMulti< EOT >(); edoEstimator< Distrib >* estimator = new edoEstimatorNormalMulti< EOT >();
state.storeFunctor(estimator); 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 >(); eoEvalFunc< EOT >* plainEval = new Rosenbrock< EOT >();
state.storeFunctor(plainEval); state.storeFunctor(plainEval);
@ -87,159 +74,65 @@ int main(int ac, char** av)
eoRndGenerator< double >* gen = new eoUniformGenerator< double >(-5, 5); eoRndGenerator< double >* gen = new eoUniformGenerator< double >(-5, 5);
state.storeFunctor(gen); state.storeFunctor(gen);
unsigned int dimension_size = parser.createParam((unsigned int)10, "dimension-size", "Dimension size", 'd', section).value(); // d 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< EOT >* init = new eoInitFixedLength< EOT >( dimension_size, *gen );
state.storeFunctor(init); state.storeFunctor(init);
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// (1) Population init and sampler // (1) Population init and sampler
//-----------------------------------------------------------------------------
// Generation of population from do_make_pop (creates parameters, manages persistance and so on...) // Generation of population from do_make_pop (creates parameters, manages persistance and so on...)
// ... and creates the parameters: L P r S // ... and creates the parameters: L P r S
// this first sampler creates a uniform distribution independently from our distribution (it does not use edoUniform).
// this first sampler creates a uniform distribution independently from our distribution (it does not use doUniform).
eoPop< EOT >& pop = do_make_pop(parser, state, *init); eoPop< EOT >& pop = do_make_pop(parser, state, *init);
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// (2) First evaluation before starting the research algorithm // (2) First evaluation before starting the research algorithm
//-----------------------------------------------------------------------------
apply(eval, pop); apply(eval, pop);
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Prepare bounder class to set bounds of sampling. // Prepare bounder class to set bounds of sampling.
// This is used by doSampler. // 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< EOT >* bounder = new edoBounderRng< EOT >(EOT(pop[0].size(), -5),
EOT(pop[0].size(), 5),
*gen);
state.storeFunctor(bounder); state.storeFunctor(bounder);
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Prepare sampler class with a specific distribution // Prepare sampler class with a specific distribution
//-----------------------------------------------------------------------------
edoSampler< Distrib >* sampler = new edoSamplerNormalMulti< EOT >( *bounder ); edoSampler< Distrib >* sampler = new edoSamplerNormalMulti< EOT >( *bounder );
state.storeFunctor(sampler); state.storeFunctor(sampler);
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Metropolis sample parameters
//-----------------------------------------------------------------------------
//unsigned int popSize = parser.getORcreateParam((unsigned int)20, "popSize", "Population Size", 'P', "Evolution Engine").value();
//moContinuator< moDummyNeighbor<EOT> >* sa_continue = new moIterContinuator< moDummyNeighbor<EOT> >( 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<EOT>* cooling_schedule = new moSimpleCoolingSchedule<EOT>(initial_temperature, alpha, 0, threshold_temperature);
//state.storeFunctor(cooling_schedule);
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// stopping criteria // stopping criteria
// ... and creates the parameter letters: C E g G s T // ... and creates the parameter letters: C E g G s T
//-----------------------------------------------------------------------------
eoContinue< EOT >& eo_continue = do_make_continue(parser, state, eval); eoContinue< EOT >& eo_continue = do_make_continue(parser, state, eval);
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// population output // population output
//-----------------------------------------------------------------------------
eoCheckPoint< EOT >& pop_continue = do_make_checkpoint(parser, state, eval, eo_continue); eoCheckPoint< EOT >& pop_continue = do_make_checkpoint(parser, state, eval, eo_continue);
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// distribution output // distribution output
//-----------------------------------------------------------------------------
edoDummyContinue< Distrib >* dummy_continue = new edoDummyContinue< Distrib >(); edoDummyContinue< Distrib >* dummy_continue = new edoDummyContinue< Distrib >();
state.storeFunctor(dummy_continue); state.storeFunctor(dummy_continue);
edoCheckPoint< Distrib >* distribution_continue = new edoCheckPoint< Distrib >( *dummy_continue ); edoCheckPoint< Distrib >* distribution_continue = new edoCheckPoint< Distrib >( *dummy_continue );
state.storeFunctor(distribution_continue); state.storeFunctor(distribution_continue);
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// eoEPRemplacement causes the using of the current and previous // eoEPRemplacement causes the using of the current and previous
// sample for sampling. // sample for sampling.
//-----------------------------------------------------------------------------
eoReplacement< EOT >* replacor = new eoEPReplacement< EOT >(pop.size()); 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); state.storeFunctor(replacor);
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Some stuff to display helper when we are using -h option // Some stuff to display helper when we are using -h option
//-----------------------------------------------------------------------------
if (parser.userNeedsHelp()) if (parser.userNeedsHelp())
{ {
parser.printHelp(std::cout); parser.printHelp(std::cout);
exit(1); exit(1);
} }
// Help + Verbose routines // Help + Verbose routines
make_verbose(parser); make_verbose(parser);
make_help(parser); make_help(parser);
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// population output (after helper) // population output (after helper)
// //
// FIXME: theses objects are instanciate there in order to avoid a folder // FIXME: theses objects are instanciated there in order to avoid a folder
// removing as doFileSnapshot does within ctor. // removing as edoFileSnapshot does within ctor.
//-----------------------------------------------------------------------------
edoPopStat< EOT >* popStat = new edoPopStat<EOT>; edoPopStat< EOT >* popStat = new edoPopStat<EOT>;
state.storeFunctor(popStat); state.storeFunctor(popStat);
pop_continue.add(*popStat); pop_continue.add(*popStat);
@ -249,13 +142,7 @@ int main(int ac, char** av)
fileSnapshot->add(*popStat); fileSnapshot->add(*popStat);
pop_continue.add(*fileSnapshot); pop_continue.add(*fileSnapshot);
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// distribution output (after helper) // distribution output (after helper)
//-----------------------------------------------------------------------------
edoDistribStat< Distrib >* distrib_stat = new edoStatNormalMulti< EOT >(); edoDistribStat< Distrib >* distrib_stat = new edoStatNormalMulti< EOT >();
state.storeFunctor(distrib_stat); state.storeFunctor(distrib_stat);
@ -271,42 +158,24 @@ int main(int ac, char** av)
file_monitor->add(*distrib_stat); file_monitor->add(*distrib_stat);
distribution_continue->add( *file_monitor ); distribution_continue->add( *file_monitor );
//----------------------------------------------------------------------------- eoPopLoopEval<EOT> popEval( eval );
//-----------------------------------------------------------------------------
// EDA algorithm configuration // EDA algorithm configuration
//-----------------------------------------------------------------------------
edoAlgo< Distrib >* algo = new edoEDA< Distrib > edoAlgo< Distrib >* algo = new edoEDA< Distrib >
(*selector, *estimator, *selectone, *modifier, *sampler, (*selector, *estimator, *sampler,
pop_continue, *distribution_continue, pop_continue, *distribution_continue,
eval, popEval, *replacor);
//*sa_continue, *cooling_schedule, initial_temperature,
*replacor);
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Beginning of the algorithm call // Beginning of the algorithm call
//----------------------------------------------------------------------------- try {
do_run(*algo, pop);
try } catch (eoEvalFuncCounterBounderException& e) {
{ eo::log << eo::warnings << "warning: " << e.what() << std::endl;
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 (std::exception& e) {
eo::log << eo::errors << "error: " << e.what() << std::endl;
exit(EXIT_FAILURE);
}
return 0; return 0;
} }

View file

@ -31,14 +31,19 @@ Authors:
#include <eoAlgo.h> #include <eoAlgo.h>
//! 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 > template < typename D >
class edoAlgo : public eoAlgo< typename D::EOType > class edoAlgo : public eoAlgo< typename D::EOType >
{ {
//! Alias for the type //! Alias for the type
typedef typename D::EOType EOT; typedef typename D::EOType EOT;
// virtual R operator()(A1) = 0; (defined in eoUF)
public: public:
virtual ~edoAlgo(){} virtual ~edoAlgo(){}
}; };

View file

@ -58,179 +58,80 @@ public:
//! edoEDA constructor //! edoEDA constructor
/*! /*!
All the boxes used by a EDASA need to be given. Takes algo operators, all are mandatory
\param selector Population Selector \param selector Selection of the best candidate solutions in the population
\param estimator Distribution Estimator \param estimator Estimation of the distribution parameters
\param selectone SelectOne \param sampler Generate feasible solutions using the distribution
\param modifier Distribution Modifier \param pop_continuator Stopping criterion based on the population features
\param sampler Distribution Sampler \param distribution_continuator Stopping criterion based on the distribution features
\param pop_continue Population Continuator \param evaluation Evaluate a population
\param distribution_continue Distribution Continuator \param replacor Replace old solutions by new ones
\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
*/ */
edoEDA (eoSelect< EOT > & selector, edoEDA (
edoEstimator< D > & estimator, eoSelect< EOT > & selector,
eoSelectOne< EOT > & selectone, edoEstimator< D > & estimator,
edoModifierMass< D > & modifier, edoSampler< D > & sampler,
edoSampler< D > & sampler, eoContinue< EOT > & pop_continuator,
eoContinue< EOT > & pop_continue, edoContinue< D > & distribution_continuator,
edoContinue< D > & distribution_continue, eoPopEvalFunc < EOT > & evaluator,
eoEvalFunc < EOT > & evaluation, eoReplacement< EOT > & replacor
//moContinuator< moDummyNeighbor<EOT> > & sa_continue, )
//moCoolingSchedule<EOT> & cooling_schedule, : _selector(selector),
//double initial_temperature, _estimator(estimator),
eoReplacement< EOT > & replacor _sampler(sampler),
) _pop_continuator(pop_continuator),
: _selector(selector), _distribution_continuator(distribution_continuator),
_estimator(estimator), _evaluator(evaluator),
_selectone(selectone), _replacor(replacor)
_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)
{} {}
//! function that launches the EDASA algorithm. /** A basic EDA algorithm that iterates over:
/*! * selection, estimation, sampling, bounding, evaluation, replacement
As a moTS or a moHC, the EDASA can be used for HYBRIDATION in an evolutionary algorithm. *
* \param pop the population of candidate solutions
\param pop A population to improve. * \return void
\return TRUE.
*/ */
void operator ()(eoPop< EOT > & pop) 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 ???
//------------------------------------------------------------- // (2) Estimation of the distribution parameters
// Estimating a first time the distribution parameter thanks distrib = _estimator(selected_pop);
// to population.
//-------------------------------------------------------------
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(); // (4) Evaluate new solutions
assert(size > 0); _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 ) );
do } // operator()
{
//-------------------------------------------------------------
// (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 );
}
private: private:
@ -240,32 +141,17 @@ private:
//! A EOT estimator. It is going to estimate distribution parameters. //! A EOT estimator. It is going to estimate distribution parameters.
edoEstimator< D > & _estimator; edoEstimator< D > & _estimator;
//! SelectOne
eoSelectOne< EOT > & _selectone;
//! A D modifier
edoModifierMass< D > & _modifier;
//! A D sampler //! A D sampler
edoSampler< D > & _sampler; edoSampler< D > & _sampler;
//! A EOT population continuator //! A EOT population continuator
eoContinue < EOT > & _pop_continue; eoContinue < EOT > & _pop_continuator;
//! A D continuator //! A D continuator
edoContinue < D > & _distribution_continue; edoContinue < D > & _distribution_continuator;
//! A full evaluation function. //! A full evaluation function.
eoEvalFunc < EOT > & _evaluation; eoPopEvalFunc < EOT > & _evaluator;
//! Stopping criterion before temperature update
//moContinuator< moDummyNeighbor<EOT> > & _sa_continue;
//! The cooling schedule
//moCoolingSchedule<EOT> & _cooling_schedule;
//! Initial temperature
//double _initial_temperature;
//! A EOT replacor //! A EOT replacor
eoReplacement < EOT > & _replacor; eoReplacement < EOT > & _replacor;