#ifndef _doCMASA_h #define _doCMASA_h //----------------------------------------------------------------------------- // Temporary solution to store populations state at each iteration for plotting. //----------------------------------------------------------------------------- // system header inclusion #include // end system header inclusion // mkdir headers inclusion #include #include // end mkdir headers inclusion #include #include #include #include #include //----------------------------------------------------------------------------- #include #include #include #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::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::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::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