This repository has been archived on 2026-03-28. You can view files and clone it, but you cannot make any changes to its state, such as pushing and creating new issues, pull requests or comments.
eodev/src/doCMASA.h
Caner Candan a038586edb + do files
2010-07-05 19:04:35 +02:00

395 lines
10 KiB
C++

#ifndef _doCMASA_h
#define _doCMASA_h
//-----------------------------------------------------------------------------
// Temporary solution to store populations state at each iteration for plotting.
//-----------------------------------------------------------------------------
// system header inclusion
#include <cstdlib>
// end system header inclusion
// mkdir headers inclusion
#include <sys/stat.h>
#include <sys/types.h>
// end mkdir headers inclusion
#include <fstream>
#include <numeric>
#include <limits>
#include <boost/numeric/ublas/vector.hpp>
#include <boost/numeric/ublas/io.hpp>
//-----------------------------------------------------------------------------
#include <eo>
#include <mo>
#include <utils/eoRNG.h>
#include "doAlgo.h"
#include "doEstimator.h"
#include "doModifierMass.h"
#include "doSampler.h"
using namespace boost::numeric::ublas;
template < typename D >
class doCMASA : public doAlgo< D >
{
public:
//! Alias for the type
typedef typename D::EOType EOT;
//! Alias for the fitness
typedef typename EOT::Fitness Fitness;
public:
//! doCMASA constructor
/*!
All the boxes used by a CMASA need to be given.
\param selector The EOT selector
\param estomator The EOT selector
\param selectone SelectOne
\param modifier The D modifier
\param sampler The D sampler
\param evaluation The evaluation function.
\param continue The stopping criterion.
\param cooling_schedule The cooling schedule, describes how the temperature is modified.
\param initial_temperature The initial temperature.
\param replacor The EOT replacor
*/
doCMASA (eoSelect< EOT > & selector,
doEstimator< D > & estimator,
eoSelectOne< EOT > & selectone,
doModifierMass< D > & modifier,
doSampler< D > & sampler,
eoContinue< EOT > & monitoring_continue,
eoEvalFunc < EOT > & evaluation,
moSolContinue < EOT > & continuator,
moCoolingSchedule & cooling_schedule,
double initial_temperature,
eoReplacement< EOT > & replacor
)
: _selector(selector),
_estimator(estimator),
_selectone(selectone),
_modifier(modifier),
_sampler(sampler),
_monitoring_continue(monitoring_continue),
_evaluation(evaluation),
_continuator(continuator),
_cooling_schedule(cooling_schedule),
_initial_temperature(initial_temperature),
_replacor(replacor)
{}
//! function that launches the CMASA algorithm.
/*!
As a moTS or a moHC, the CMASA can be used for HYBRIDATION in an evolutionary algorithm.
\param pop A population to improve.
\return TRUE.
*/
//bool operator ()(eoPop< EOT > & pop)
void operator ()(eoPop< EOT > & pop)
{
assert(pop.size() > 0);
double temperature = _initial_temperature;
eoPop< EOT > current_pop = pop;
eoPop< EOT > selected_pop;
//-------------------------------------------------------------
// Temporary solution used by plot to enumerate iterations in
// several files.
//-------------------------------------------------------------
int number_of_iterations = 0;
//-------------------------------------------------------------
//-------------------------------------------------------------
// Temporary solution to store populations state at each
// iteration for plotting.
//-------------------------------------------------------------
std::string pop_results_destination("ResPop");
{
std::stringstream ss;
ss << "rm -rf " << pop_results_destination;
::system(ss.str().c_str());
}
::mkdir(pop_results_destination.c_str(), 0755); // create a first time the
// directory where populations state are going to be stored.
std::ofstream ofs_params("ResParams.txt");
std::ofstream ofs_params_var("ResVars.txt");
//-------------------------------------------------------------
//-------------------------------------------------------------
// Temporary solution to store bounds valeur for each distribution.
//-------------------------------------------------------------
std::string bounds_results_destination("ResBounds");
{
std::stringstream ss;
ss << "rm -rf " << bounds_results_destination;
::system(ss.str().c_str());
}
::mkdir(bounds_results_destination.c_str(), 0755); // create a first time the
//-------------------------------------------------------------
{
D distrib = _estimator(pop);
double size = distrib.size();
assert(size > 0);
double vacc = 1;
for (int i = 0; i < size; ++i)
{
vacc *= sqrt(distrib.variance()[i]);
}
assert(vacc <= std::numeric_limits<double>::max());
ofs_params_var << vacc << std::endl;
}
do
{
if (pop != current_pop)
{
_replacor(pop, current_pop);
}
current_pop.clear();
selected_pop.clear();
//-------------------------------------------------------------
// (3) Selection of the best points in the population
//-------------------------------------------------------------
_selector(pop, selected_pop);
//-------------------------------------------------------------
_continuator.init();
//-------------------------------------------------------------
// (4) Estimation of the distribution parameters
//-------------------------------------------------------------
D 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);
//-------------------------------------------------------------
//-------------------------------------------------------------
// Building of the sampler in current_pop
//-------------------------------------------------------------
do
{
EOT candidate_solution = _sampler(distrib);
EOT& e1 = candidate_solution;
_evaluation( e1 );
EOT& e2 = current_solution;
_evaluation( e2 );
// TODO: verifier le critere d'acceptation
if ( e1.fitness() < e2.fitness() ||
rng.uniform() < exp( ::fabs(e1.fitness() - e2.fitness()) / temperature ) )
{
current_pop.push_back(candidate_solution);
current_solution = candidate_solution;
}
}
while ( _continuator( current_solution) );
//-------------------------------------------------------------
// Temporary solution to store populations state
// at each iteration for plotting.
//-------------------------------------------------------------
{
std::stringstream ss;
ss << pop_results_destination << "/" << number_of_iterations;
std::ofstream ofs(ss.str().c_str());
ofs << current_pop;
}
//-------------------------------------------------------------
//-------------------------------------------------------------
// Temporary solution used by plot to enumerate iterations in
// several files.
//-------------------------------------------------------------
{
double size = distrib.size();
assert(size > 0);
std::stringstream ss;
ss << bounds_results_destination << "/" << number_of_iterations;
std::ofstream ofs(ss.str().c_str());
ofs << size << " ";
std::copy(distrib.param(0).begin(), distrib.param(0).end(), std::ostream_iterator< double >(ofs, " "));
std::copy(distrib.param(1).begin(), distrib.param(1).end(), std::ostream_iterator< double >(ofs, " "));
ofs << std::endl;
}
//-------------------------------------------------------------
//-------------------------------------------------------------
// Temporary saving to get a proof for distribution bounds
// dicreasement
//-------------------------------------------------------------
{
// double size = distrib.size();
// assert(size > 0);
// vector< double > vmin(size);
// vector< double > vmax(size);
// std::copy(distrib.param(0).begin(), distrib.param(0).end(), vmin.begin());
// std::copy(distrib.param(1).begin(), distrib.param(1).end(), vmax.begin());
// vector< double > vrange = vmax - vmin;
// double vacc = 1;
// for (int i = 0, size = vrange.size(); i < size; ++i)
// {
// vacc *= vrange(i);
// }
// assert(vacc <= std::numeric_limits<double>::max());
// ofs_params << vacc << std::endl;
}
//-------------------------------------------------------------
//-------------------------------------------------------------
// Temporary saving to get a proof for distribution bounds
// dicreasement
//-------------------------------------------------------------
{
double size = distrib.size();
assert(size > 0);
double vacc = 1;
for (int i = 0; i < size; ++i)
{
vacc *= sqrt(distrib.variance()[i]);
}
assert(vacc <= std::numeric_limits<double>::max());
ofs_params_var << vacc << std::endl;
}
//-------------------------------------------------------------
++number_of_iterations;
}
while ( _cooling_schedule( temperature ) &&
_monitoring_continue( selected_pop ) );
}
private:
//! A EOT selector
eoSelect < EOT > & _selector;
//! A EOT estimator. It is going to estimate distribution parameters.
doEstimator< D > & _estimator;
//! SelectOne
eoSelectOne< EOT > & _selectone;
//! A D modifier
doModifierMass< D > & _modifier;
//! A D sampler
doSampler< D > & _sampler;
//! A EOT monitoring continuator
eoContinue < EOT > & _monitoring_continue;
//! A full evaluation function.
eoEvalFunc < EOT > & _evaluation;
//! Stopping criterion before temperature update
moSolContinue < EOT > & _continuator;
//! The cooling schedule
moCoolingSchedule & _cooling_schedule;
//! Initial temperature
double _initial_temperature;
//! A EOT replacor
eoReplacement < EOT > & _replacor;
};
#endif // !_doCMASA_h