From 0c5545c421d0ab996b1b8610849f06c5c08634c5 Mon Sep 17 00:00:00 2001 From: Caner Candan Date: Mon, 23 Aug 2010 15:56:58 +0200 Subject: [PATCH] + plot populations by generation - removed dump from doEDASA --- application/eda_sa/main.cpp | 86 ++++++++++++---- src/do | 3 + src/doEDASA.h | 196 ++---------------------------------- src/doFileSnapshot.cpp | 119 ++++++++++++++++++++++ src/doFileSnapshot.h | 189 ++++++---------------------------- src/doPopStat.h | 75 ++++++++++++++ 6 files changed, 299 insertions(+), 369 deletions(-) create mode 100644 src/doFileSnapshot.cpp create mode 100644 src/doPopStat.h diff --git a/application/eda_sa/main.cpp b/application/eda_sa/main.cpp index e689d936..b362529c 100644 --- a/application/eda_sa/main.cpp +++ b/application/eda_sa/main.cpp @@ -24,18 +24,19 @@ int main(int ac, char** av) { eoParserLogger parser(ac, av); - // Letters used by the following declarations : + // Letters used by the following declarations: // a d i p t std::string section("Algorithm parameters"); - // FIXME: a verifier la valeur par defaut + // FIXME: default value to check double initial_temperature = parser.createParam((double)10e5, "temperature", "Initial temperature", 'i', section).value(); // i eoState state; + //----------------------------------------------------------------------------- - // Instantiate all need parameters for EDASA algorithm + // Instantiate all needed parameters for EDASA algorithm //----------------------------------------------------------------------------- eoSelect< EOT >* selector = new eoDetSelect< EOT >(0.5); @@ -81,10 +82,10 @@ int main(int ac, char** av) // (1) Population init and sampler //----------------------------------------------------------------------------- - // Generation of population from do_make_pop (creates parameter, manages persistance and so on...) - // ... and creates the parameter letters: L P r S + // 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 of our distribution (it doesnot use doUniform). + // 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); @@ -100,18 +101,37 @@ int main(int ac, char** av) //----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- + // Prepare bounder class to set bounds of sampling. + // This is used by doSampler. + //----------------------------------------------------------------------------- + + //doBounder< EOT >* bounder = new doBounderNo< EOT >(); doBounder< EOT >* bounder = new doBounderRng< EOT >(EOT(pop[0].size(), -5), EOT(pop[0].size(), 5), *gen); state.storeFunctor(bounder); + //----------------------------------------------------------------------------- + + + //----------------------------------------------------------------------------- + // Prepare sampler class with a specific distribution + //----------------------------------------------------------------------------- + doSampler< Distrib >* sampler = //new doSamplerUniform< EOT >(); //new doSamplerNormalMono< EOT >( *bounder ); new doSamplerNormalMulti< EOT >( *bounder ); state.storeFunctor(sampler); + //----------------------------------------------------------------------------- + + + //----------------------------------------------------------------------------- + // Metropolis sample parameters + //----------------------------------------------------------------------------- // FIXME: should I set the default value of rho to pop size ?!? @@ -120,42 +140,63 @@ int main(int ac, char** av) moGenSolContinue< EOT >* sa_continue = new moGenSolContinue< EOT >(rho); state.storeFunctor(sa_continue); + //----------------------------------------------------------------------------- + + + //----------------------------------------------------------------------------- + // SA parameters + //----------------------------------------------------------------------------- + double threshold = parser.createParam((double)0.1, "threshold", "Threshold: temperature threshold stopping criteria", 't', section).value(); // t double alpha = parser.createParam((double)0.1, "alpha", "Alpha: temperature dicrease rate", 'a', section).value(); // a moCoolingSchedule* cooling_schedule = new moGeometricCoolingSchedule(threshold, alpha); 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); - // output + //----------------------------------------------------------------------------- + + + //----------------------------------------------------------------------------- + // general output + //----------------------------------------------------------------------------- eoCheckPoint< EOT >& monitoring_continue = do_make_checkpoint(parser, state, eval, eo_continue); - // eoPopStat< EOT >* popStat = new eoPopStat; - // state.storeFunctor(popStat); + //----------------------------------------------------------------------------- - // checkpoint.add(*popStat); - // eoGnuplot1DMonitor* gnuplot = new eoGnuplot1DMonitor("gnuplot.txt"); - // state.storeFunctor(gnuplot); + //----------------------------------------------------------------------------- + // population output + //----------------------------------------------------------------------------- - // gnuplot->add(eval); - // gnuplot->add(*popStat); + eoCheckPoint< EOT >* pop_continue = new eoCheckPoint< EOT >( eo_continue ); + state.storeFunctor(pop_continue); - //gnuplot->gnuplotCommand("set yrange [0:500]"); + doPopStat< EOT >* popStat = new doPopStat; + state.storeFunctor(popStat); + pop_continue->add(*popStat); - // checkpoint.add(*gnuplot); + doFileSnapshot* fileSnapshot = new doFileSnapshot("ResPop"); + state.storeFunctor(fileSnapshot); + fileSnapshot->add(*popStat); + pop_continue->add(*fileSnapshot); - // eoMonitor* fileSnapshot = new doFileSnapshot< std::vector< std::string > >("ResPop"); - // state.storeFunctor(fileSnapshot); + //----------------------------------------------------------------------------- - // fileSnapshot->add(*popStat); - // checkpoint.add(*fileSnapshot); + //----------------------------------------------------------------------------- + // distribution output + //----------------------------------------------------------------------------- doDummyContinue< Distrib >* dummy_continue = new doDummyContinue< Distrib >(); state.storeFunctor(dummy_continue); @@ -178,6 +219,9 @@ int main(int ac, char** av) file_monitor->add(*distrib_stat); distribution_continue->add( *file_monitor ); + //----------------------------------------------------------------------------- + + //----------------------------------------------------------------------------- // eoEPRemplacement causes the using of the current and previous // sample for sampling. @@ -200,7 +244,7 @@ int main(int ac, char** av) doAlgo< Distrib >* algo = new doEDASA< Distrib > (*selector, *estimator, *selectone, *modifier, *sampler, - monitoring_continue, *distribution_continue, + monitoring_continue, *pop_continue, *distribution_continue, eval, *sa_continue, *cooling_schedule, initial_temperature, *replacor); diff --git a/src/do b/src/do index 74df1ca1..e96262c9 100644 --- a/src/do +++ b/src/do @@ -48,4 +48,7 @@ #include "doStatNormalMono.h" #include "doStatNormalMulti.h" +#include "doFileSnapshot.h" +#include "doPopStat.h" + #endif // !_do_ diff --git a/src/doEDASA.h b/src/doEDASA.h index 35cec339..25fc5e5d 100644 --- a/src/doEDASA.h +++ b/src/doEDASA.h @@ -8,29 +8,6 @@ #ifndef _doEDASA_h #define _doEDASA_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 @@ -44,8 +21,6 @@ #include "doStat.h" #include "doContinue.h" -using namespace boost::numeric::ublas; - template < typename D > class doEDASA : public doAlgo< D > { @@ -82,6 +57,7 @@ public: doModifierMass< D > & modifier, doSampler< D > & sampler, eoContinue< EOT > & monitoring_continue, + eoContinue< EOT > & pop_continue, doContinue< D > & distribution_continue, eoEvalFunc < EOT > & evaluation, moSolContinue < EOT > & sa_continue, @@ -95,53 +71,14 @@ public: _modifier(modifier), _sampler(sampler), _monitoring_continue(monitoring_continue), + _pop_continue(pop_continue), _distribution_continue(distribution_continue), _evaluation(evaluation), _sa_continue(sa_continue), _cooling_schedule(cooling_schedule), _initial_temperature(initial_temperature), - _replacor(replacor), - - _pop_results_destination("ResPop")//, - - // directory where populations state are going to be stored. - // _ofs_params("ResParams.txt"), - // _ofs_params_var("ResVars.txt"), - - // _bounds_results_destination("ResBounds") - { - - //------------------------------------------------------------- - // Temporary solution to store populations state at each - // iteration for plotting. - //------------------------------------------------------------- - - { - std::stringstream os; - os << "rm -rf " << _pop_results_destination; - ::system(os.str().c_str()); - } - - ::mkdir(_pop_results_destination.c_str(), 0755); // create a first time - - //------------------------------------------------------------- - - - //------------------------------------------------------------- - // Temporary solution to store bounds values for each distribution. - //------------------------------------------------------------- - - // { - // std::stringstream os; - // os << "rm -rf " << _bounds_results_destination; - // ::system(os.str().c_str()); - // } - - //::mkdir(_bounds_results_destination.c_str(), 0755); // create once directory - - //------------------------------------------------------------- - - } + _replacor(replacor) + {} //! function that launches the EDASA algorithm. /*! @@ -150,7 +87,6 @@ public: \param pop A population to improve. \return TRUE. */ - //bool operator ()(eoPop< EOT > & pop) void operator ()(eoPop< EOT > & pop) { assert(pop.size() > 0); @@ -162,16 +98,6 @@ public: eoPop< EOT > selected_pop; - //------------------------------------------------------------- - // Temporary solution used by plot to enumerate iterations in - // several files. - //------------------------------------------------------------- - - int number_of_iterations = 0; - - //------------------------------------------------------------- - - //------------------------------------------------------------- // Estimating a first time the distribution parameter thanks // to population. @@ -185,22 +111,6 @@ public: //------------------------------------------------------------- - // { - // D distrib = _estimator(pop); - - // double size = distrib.size(); - // assert(size > 0); - - // doHyperVolume< EOT > hv; - - // for (int i = 0; i < size; ++i) - // { - // //hv.update( distrib.varcovar()[i] ); - // } - - // // _ofs_params_var << hv << std::endl; - // } - do { if (pop != current_pop) @@ -283,102 +193,10 @@ public: } while ( _sa_continue( current_solution) ); - - //------------------------------------------------------------- - // Temporary solution to store populations state - // at each iteration for plotting. - //------------------------------------------------------------- - - { - std::ostringstream os; - os << _pop_results_destination << "/" << number_of_iterations; - std::ofstream ofs(os.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 os; - // os << _bounds_results_destination << "/" << number_of_iterations; - // std::ofstream ofs(os.str().c_str()); - - // ofs << size << " "; - //ublas::vector< AtomType > mean = distrib.mean(); - //std::copy(mean.begin(), mean.end(), std::ostream_iterator< double >(ofs, " ")); - //std::copy(distrib.varcovar().begin(), distrib.varcovar().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; - - // doHyperVolume hv; - - // for (int i = 0, size = vrange.size(); i < size; ++i) - // { - // hv.update( vrange(i) ); - // } - - // ofs_params << hv << std::endl; - // } - - //------------------------------------------------------------- - - - //------------------------------------------------------------- - // Temporary saving to get a proof for distribution bounds - // dicreasement - //------------------------------------------------------------- - - // { - // double size = distrib.size(); - // assert(size > 0); - - // doHyperVolume< EOT > hv; - - // for (int i = 0; i < size; ++i) - // { - // //hv.update( distrib.varcovar()[i] ); - // } - - // //_ofs_params_var << hv << std::endl; - // } - - //------------------------------------------------------------- - - ++number_of_iterations; - } while ( _cooling_schedule( temperature ) && _distribution_continue( distrib ) && + _pop_continue( current_pop ) && _monitoring_continue( selected_pop ) ); } @@ -403,6 +221,9 @@ private: //! A EOT monitoring continuator eoContinue < EOT > & _monitoring_continue; + //! A EOT population continuator + eoContinue < EOT > & _pop_continue; + //! A D continuator doContinue < D > & _distribution_continue; @@ -426,7 +247,6 @@ private: // iteration for plotting. //------------------------------------------------------------- - std::string _pop_results_destination; // std::ofstream _ofs_params; // std::ofstream _ofs_params_var; diff --git a/src/doFileSnapshot.cpp b/src/doFileSnapshot.cpp new file mode 100644 index 00000000..0bda8ea6 --- /dev/null +++ b/src/doFileSnapshot.cpp @@ -0,0 +1,119 @@ +//----------------------------------------------------------------------------- +// doFileSnapshot.cpp +// (c) Marc Schoenauer, Maarten Keijzer and GeNeura Team, 2001 +/* + 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 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Contact: todos@geneura.ugr.es, http://geneura.ugr.es + Marc.Schoenauer@polytechnique.fr + mkeijzer@dhi.dk + Johann Dreo + Caner Candan + */ +//----------------------------------------------------------------------------- + +#include +#include +#include + +#include +#include +#include + +doFileSnapshot::doFileSnapshot(std::string dirname, + unsigned int frequency /*= 1*/, + std::string filename /*= "gen"*/, + std::string delim /*= " "*/, + unsigned int counter /*= 0*/, + bool rmFiles /*= true*/) + : _dirname(dirname), _frequency(frequency), + _filename(filename), _delim(delim), + _counter(counter), _boolChanged(true) +{ + std::string s = "test -d " + _dirname; + + int res = system(s.c_str()); + + // test for (unlikely) errors + + if ( (res == -1) || (res == 127) ) + { + throw std::runtime_error("Problem executing test of dir in eoFileSnapshot"); + } + + // now make sure there is a dir without any genXXX file in it + if (res) // no dir present + { + s = std::string("mkdir ") + _dirname; + } + else if (!res && rmFiles) + { + s = std::string("/bin/rm ") + _dirname+ "/" + _filename + "*"; + } + else + { + s = " "; + } + + int dummy; + dummy = system(s.c_str()); + // all done +} + + +void doFileSnapshot::setCurrentFileName() +{ + std::ostringstream oscount; + oscount << _counter; + _currentFileName = _dirname + "/" + _filename + oscount.str(); +} + +eoMonitor& doFileSnapshot::operator()(void) +{ + if (_counter % _frequency) + { + _boolChanged = false; // subclass with gnuplot will do nothing + _counter++; + return (*this); + } + _counter++; + _boolChanged = true; + setCurrentFileName(); + std::ofstream os(_currentFileName.c_str()); + + if (!os) + { + std::string str = "doFileSnapshot: Could not open " + _currentFileName; + throw std::runtime_error(str); + } + + return operator()(os); +} + +eoMonitor& doFileSnapshot::operator()(std::ostream& os) +{ + iterator it = vec.begin(); + + os << (*it)->getValue(); + + for ( ++it; it != vec.end(); ++it ) + { + os << _delim.c_str() << (*it)->getValue(); + } + + os << '\n'; + + return *this; +} diff --git a/src/doFileSnapshot.h b/src/doFileSnapshot.h index def9efc2..9329eed9 100644 --- a/src/doFileSnapshot.h +++ b/src/doFileSnapshot.h @@ -1,5 +1,5 @@ //----------------------------------------------------------------------------- -// eoFileSnapshot.h +// doFileSnapshot.h // (c) Marc Schoenauer, Maarten Keijzer and GeNeura Team, 2001 /* This library is free software; you can redistribute it and/or @@ -19,182 +19,51 @@ Contact: todos@geneura.ugr.es, http://geneura.ugr.es Marc.Schoenauer@polytechnique.fr mkeijzer@dhi.dk - Caner Candan caner@candan.fr - Johann Dréo nojhan@gmail.com + Johann Dreo + Caner Candan */ //----------------------------------------------------------------------------- #ifndef _doFileSnapshot_h #define _doFileSnapshot_h -#include // for mkdir -#include // for mkdir -#include // for unlink - -#include -#include #include +#include +#include -#include -#include -#include +#include "utils/eoMonitor.h" -#include - -/** -Prints snapshots of fitnesses to a (new) file every N generations - -Assumes that the parameters that are passed to the monitor -(method add in eoMonitor.h) are eoValueParam > of same size. - -A dir is created and one file per snapshot is created there - -so you can later generate a movie! - -TODO: The counter is handled internally, but this should be changed -so that you can pass e.g. an evalcounter (minor) - -I failed to templatize everything so that it can handle eoParam > -for any type T, simply calling their getValue method ... -*/ - -template < typename EOTParam > class doFileSnapshot : public eoMonitor { -public : - doFileSnapshot(std::string _dirname, unsigned _frequency = 1, - std::string _filename = "gen", - std::string _delim = " ", unsigned _counter = 0, - bool _rmFiles = true): - dirname(_dirname), frequency(_frequency), - filename(_filename), delim(_delim), counter(_counter), boolChanged(true) - { - // FIXME START - // TO REPLACE test command by somethink more gernerical +public: - std::string s = "test -d " + dirname; + doFileSnapshot(std::string dirname, + unsigned int frequency = 1, + std::string filename = "gen", + std::string delim = " ", + unsigned int counter = 0, + bool rmFiles = true); - int res = system(s.c_str()); - // test for (unlikely) errors - if ( (res==-1) || (res==127) ) - throw std::runtime_error("Problem executing test of dir in eoFileSnapshot"); + virtual bool hasChanged() {return _boolChanged;} + virtual std::string getDirName() { return _dirname; } + virtual unsigned int getCounter() { return _counter; } + virtual const std::string baseFileName() { return _filename;} + std::string getFileName() {return _currentFileName;} - // FIXME END + void setCurrentFileName(); - // now make sure there is a dir without any genXXX file in it - if (res) // no dir present - { - ::mkdir(dirname.c_str(), 0755); - } - else if (!res && _rmFiles) - { - std::string s = dirname+ "/" + filename + "*"; - ::unlink(s.c_str()); - } - } + virtual eoMonitor& operator()(void); - /** accessor: has something changed (for gnuplot subclass) - */ - virtual bool hasChanged() {return boolChanged;} - - /** accessor to the counter: needed by the gnuplot subclass - */ - unsigned getCounter() {return counter;} - - /** accessor to the current filename: needed by the gnuplot subclass - */ - std::string getFileName() {return currentFileName;} - - /** sets the current filename depending on the counter - */ - void setCurrentFileName() - { - std::ostringstream oscount; - oscount << counter; - currentFileName = dirname + "/" + filename + oscount.str(); - } - - /** The operator(void): opens the std::ostream and calls the write method - */ - eoMonitor& operator()(void) - { - if (counter % frequency) - { - boolChanged = false; // subclass with gnuplot will do nothing - counter++; - return (*this); - } - counter++; - boolChanged = true; - setCurrentFileName(); - std::ofstream os(currentFileName.c_str()); - - if (!os) - { - std::string str = "eoFileSnapshot: Could not open " + currentFileName; - throw std::runtime_error(str); - } - - return operator()(os); - } - - /** The operator(): write on an std::ostream - */ - eoMonitor& operator()(std::ostream& _os) - { - const eoValueParam< EOTParam > * ptParam = - static_cast< const eoValueParam< EOTParam >* >(vec[0]); - - EOTParam v(ptParam->value()); - if (vec.size() == 1) // only one std::vector: -> add number in front - { - eo::log << "I am here..." << std::endl; - - for (unsigned k=0; k vv(vec.size()); - vv[0]=v; - for (unsigned i=1; i* >(vec[1]); - vv[i] = ptParam->value(); - if (vv[i].size() != v.size()) - throw std::runtime_error("Dimension error in eoSnapshotMonitor"); - } - for (unsigned k=0; k + Caner Candan + */ +//----------------------------------------------------------------------------- + +/** WARNING: this file contains 2 classes: + +eoPopString and eoSortedPopString + +that transform the population into a std::string +that can be used to dump to the screen +*/ + +#ifndef _doPopStat_h +#define _doPopStat_h + +#include + + +/** Thanks to MS/VC++, eoParam mechanism is unable to handle std::vectors of stats. +This snippet is a workaround: +This class will "print" a whole population into a std::string - that you can later +send to any stream +This is the plain version - see eoPopString for the Sorted version + +Note: this Stat should probably be used only within eoStdOutMonitor, and not +inside an eoFileMonitor, as the eoState construct will work much better there. +*/ +template +class doPopStat : public eoStat +{ +public: + + using eoStat::value; + + /** default Ctor, void std::string by default, as it appears + on the description line once at beginning of evolution. and + is meaningless there. _howMany defaults to 0, that is, the whole + population*/ + doPopStat(std::string _desc ="") + : eoStat("", _desc) {} + + /** Fills the value() of the eoParam with the dump of the population. */ + void operator()(const eoPop& _pop) + { + std::ostringstream os; + os << _pop; + value() = os.str(); + } +}; + +#endif // !_doPopStat_h