EvolvingObjects
|
00001 // -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- 00002 00003 //----------------------------------------------------------------------------- 00004 // make_checkpoint.h 00005 // (c) Maarten Keijzer, Marc Schoenauer and GeNeura Team, 2000 00006 /* 00007 This library is free software; you can redistribute it and/or 00008 modify it under the terms of the GNU Lesser General Public 00009 License as published by the Free Software Foundation; either 00010 version 2 of the License, or (at your option) any later version. 00011 00012 This library is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 Lesser General Public License for more details. 00016 00017 You should have received a copy of the GNU Lesser General Public 00018 License along with this library; if not, write to the Free Software 00019 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00020 00021 Contact: todos@geneura.ugr.es, http://geneura.ugr.es 00022 Marc.Schoenauer@polytechnique.fr 00023 mkeijzer@dhi.dk 00024 */ 00025 //----------------------------------------------------------------------------- 00026 00027 #ifndef _make_checkpoint_h 00028 #define _make_checkpoint_h 00029 00030 #ifdef HAVE_CONFIG_H 00031 #include <config.h> 00032 #endif 00033 00034 #include <climits> 00035 00036 #include <eoScalarFitness.h> 00037 #include <utils/selectors.h> // for minimizing_fitness() 00038 #include <EO.h> 00039 #include <eoEvalFuncCounter.h> 00040 #include <utils/checkpointing> 00041 00042 // at the moment, in utils/make_help.cpp 00043 // this should become some eoUtils.cpp with corresponding eoUtils.h 00044 bool testDirRes(std::string _dirName, bool _erase); 00046 00054 template <class EOT> 00055 eoCheckPoint<EOT>& do_make_checkpoint(eoParser& _parser, eoState& _state, eoValueParam<unsigned long>& _eval, eoContinue<EOT>& _continue) 00056 { 00057 // first, create a checkpoint from the eoContinue 00058 eoCheckPoint<EOT> *checkpoint = new eoCheckPoint<EOT>(_continue); 00059 00060 _state.storeFunctor(checkpoint); 00061 00063 // Signal monitoring 00065 00066 #ifndef _MSC_VER 00067 // the CtrlC monitoring interception 00068 eoSignal<EOT> *mon_ctrlCCont; 00069 eoValueParam<bool>& mon_ctrlCParam = _parser.createParam(false, "monitor-with-CtrlC", "Monitor current generation upon Ctrl C",0, "Stopping criterion"); 00070 if (mon_ctrlCParam.value()) 00071 { 00072 mon_ctrlCCont = new eoSignal<EOT>; 00073 // store 00074 _state.storeFunctor(mon_ctrlCCont); 00075 // add to checkpoint 00076 checkpoint->add(*mon_ctrlCCont); 00077 } 00078 #endif 00079 00081 // Counters 00083 00084 // is nb Eval to be used as counter? 00085 eoValueParam<bool>& useEvalParam = _parser.createParam(true, "useEval", "Use nb of eval. as counter (vs nb of gen.)", '\0', "Output"); 00086 eoValueParam<bool>& useTimeParam = _parser.createParam(true, "useTime", "Display time (s) every generation", '\0', "Output"); 00087 // if we want the time, we need an eoTimeCounter 00088 eoTimeCounter * tCounter = NULL; 00089 00090 // Create anyway a generation-counter 00091 // Recent change (03/2002): it is now an eoIncrementorParam, both 00092 // a parameter AND updater so you can store it into the eoState 00093 eoIncrementorParam<unsigned> *generationCounter = new eoIncrementorParam<unsigned>("Gen."); 00094 00095 // store it in the state 00096 _state.storeFunctor(generationCounter); 00097 00098 // And add it to the checkpoint, 00099 checkpoint->add(*generationCounter); 00100 00101 // dir for DISK output 00102 eoValueParam<std::string>& dirNameParam = _parser.createParam(std::string("Res"), "resDir", "Directory to store DISK outputs", '\0', "Output - Disk"); 00103 00104 // shoudl we empty it if exists 00105 eoValueParam<bool>& eraseParam = _parser.createParam(true, "eraseDir", "erase files in dirName if any", '\0', "Output - Disk"); 00106 00107 bool dirOK = false; // not tested yet 00108 00110 // now some statistics on the population: 00112 00123 // Best fitness in population 00124 //--------------------------- 00125 eoValueParam<bool>& printBestParam = _parser.createParam(true, "printBestStat", "Print Best/avg/stdev every gen.", '\0', "Output"); 00126 eoValueParam<bool>& plotBestParam = _parser.createParam(false, "plotBestStat", "Plot Best/avg Stat", '\0', "Output - Graphical"); 00127 eoValueParam<bool>& fileBestParam = _parser.createParam(false, "fileBestStat", "Output bes/avg/std to file", '\0', "Output - Disk"); 00128 00129 eoBestFitnessStat<EOT> *bestStat = NULL; 00130 if ( printBestParam.value() || plotBestParam.value() || fileBestParam.value() ) 00131 // we need the bestStat for at least one of the 3 above 00132 { 00133 bestStat = new eoBestFitnessStat<EOT>; 00134 // store it 00135 _state.storeFunctor(bestStat); 00136 // add it to the checkpoint 00137 checkpoint->add(*bestStat); 00138 // check if monitoring with signal 00139 if ( mon_ctrlCParam.value() ) 00140 mon_ctrlCCont->add(*bestStat); 00141 } 00142 00143 // Average fitness alone 00144 //---------------------- 00145 eoAverageStat<EOT> *averageStat = NULL; // do we need averageStat? 00146 if ( printBestParam.value() || plotBestParam.value() || fileBestParam.value() ) // we need it for gnuplot output 00147 { 00148 averageStat = new eoAverageStat<EOT>; 00149 // store it 00150 _state.storeFunctor(averageStat); 00151 // add it to the checkpoint 00152 checkpoint->add(*averageStat); 00153 // check if monitoring with signal 00154 if ( mon_ctrlCParam.value() ) 00155 mon_ctrlCCont->add(*averageStat); 00156 } 00157 00158 // Second moment stats: average and stdev 00159 //--------------------------------------- 00160 eoSecondMomentStats<EOT> *secondStat = NULL; 00161 if ( printBestParam.value() || fileBestParam.value() ) // we need it for screen output or file output 00162 { 00163 secondStat = new eoSecondMomentStats<EOT>; 00164 // store it 00165 _state.storeFunctor(secondStat); 00166 // add it to the checkpoint 00167 checkpoint->add(*secondStat); 00168 // check if monitoring with signal 00169 if ( mon_ctrlCParam.value() ) 00170 mon_ctrlCCont->add(*secondStat); 00171 } 00172 00173 // Dump of the whole population 00174 //----------------------------- 00175 eoSortedPopStat<EOT> *popStat = NULL; 00176 eoValueParam<bool>& printPopParam = _parser.createParam(false, "printPop", "Print sorted pop. every gen.", '\0', "Output"); 00177 00178 if ( printPopParam.value() ) // we do want pop dump 00179 { 00180 popStat = new eoSortedPopStat<EOT>; 00181 // store it 00182 _state.storeFunctor(popStat); 00183 // add it to the checkpoint 00184 checkpoint->add(*popStat); 00185 // check if monitoring with signal 00186 if ( mon_ctrlCParam.value() ) 00187 mon_ctrlCCont->add(*popStat); 00188 } 00189 00190 // do we wnat some histogram of fitnesses snpashots? 00191 eoValueParam<bool> plotHistogramParam = _parser.createParam(false, "plotHisto", "Plot histogram of fitnesses", '\0', "Output - Graphical"); 00192 00194 // The monitors 00196 00197 // do we want an eoStdoutMonitor? 00198 bool needStdoutMonitor = printBestParam.value() 00199 || printPopParam.value() ; 00200 00201 // The Stdout monitor will print parameters to the screen ... 00202 if ( needStdoutMonitor ) 00203 { 00204 eoStdoutMonitor *monitor = new eoStdoutMonitor(/*false FIXME remove this deprecated prototype*/); 00205 _state.storeFunctor(monitor); 00206 00207 // when called by the checkpoint (i.e. at every generation) 00208 // check if monitoring with signal 00209 if ( ! mon_ctrlCParam.value() ) 00210 checkpoint->add(*monitor); 00211 else 00212 mon_ctrlCCont->add(*monitor); 00213 00214 // the monitor will output a series of parameters: add them 00215 monitor->add(*generationCounter); 00216 00217 if (useEvalParam.value()) // we want nb of evaluations 00218 monitor->add(_eval); 00219 if (useTimeParam.value()) // we want time 00220 { 00221 tCounter = new eoTimeCounter; 00222 _state.storeFunctor(tCounter); 00223 // check if monitoring with signal 00224 if ( ! mon_ctrlCParam.value() ) 00225 checkpoint->add(*tCounter); 00226 else 00227 mon_ctrlCCont->add(*tCounter); 00228 monitor->add(*tCounter); 00229 } 00230 00231 if (printBestParam.value()) 00232 { 00233 monitor->add(*bestStat); 00234 monitor->add(*secondStat); 00235 } 00236 00237 if ( printPopParam.value()) 00238 monitor->add(*popStat); 00239 } 00240 00241 // first handle the dir test - if we need at least one file 00242 if ( ( fileBestParam.value() || plotBestParam.value() || 00243 plotHistogramParam.value() ) 00244 && !dirOK ) // just in case we add something before 00245 dirOK = testDirRes(dirNameParam.value(), eraseParam.value()); // TRUE 00246 00247 if (fileBestParam.value()) // A file monitor for best & secondMoment 00248 { 00249 #ifdef _MSVC 00250 std::string stmp = dirNameParam.value() + "\best.xg"; 00251 #else 00252 std::string stmp = dirNameParam.value() + "/best.xg"; 00253 #endif 00254 eoFileMonitor *fileMonitor = new eoFileMonitor(stmp); 00255 // save and give to checkpoint 00256 _state.storeFunctor(fileMonitor); 00257 checkpoint->add(*fileMonitor); 00258 // and feed with some statistics 00259 fileMonitor->add(*generationCounter); 00260 fileMonitor->add(_eval); 00261 if (tCounter) // we want the time as well 00262 { 00263 // std::cout << "On met timecounter\n"; 00264 fileMonitor->add(*tCounter); 00265 } 00266 fileMonitor->add(*bestStat); 00267 fileMonitor->add(*secondStat); 00268 } 00269 00270 #if defined(HAVE_GNUPLOT) 00271 if (plotBestParam.value()) // an eoGnuplot1DMonitor for best & average 00272 { 00273 std::string stmp = dirNameParam.value() + "/gnu_best.xg"; 00274 eoGnuplot1DMonitor *gnuMonitor = new eoGnuplot1DMonitor(stmp,minimizing_fitness<EOT>()); 00275 // save and give to checkpoint 00276 _state.storeFunctor(gnuMonitor); 00277 checkpoint->add(*gnuMonitor); 00278 // and feed with some statistics 00279 if (useEvalParam.value()) // do we want eval as X coordinate 00280 gnuMonitor->add(_eval); 00281 else if (tCounter) // or time? 00282 gnuMonitor->add(*tCounter); 00283 else // default: generation 00284 gnuMonitor->add(*generationCounter); 00285 gnuMonitor->add(*bestStat); 00286 gnuMonitor->add(*averageStat); 00287 } 00288 00289 // historgram? 00290 if (plotHistogramParam.value()) // want to see how the fitness is spread? 00291 { 00292 eoScalarFitnessStat<EOT> *fitStat = new eoScalarFitnessStat<EOT>; 00293 _state.storeFunctor(fitStat); 00294 checkpoint->add(*fitStat); 00295 // a gnuplot-based monitor for snapshots: needs a dir name 00296 eoGnuplot1DSnapshot *fitSnapshot = new eoGnuplot1DSnapshot(dirNameParam.value()); 00297 _state.storeFunctor(fitSnapshot); 00298 // add any stat that is a std::vector<double> to it 00299 fitSnapshot->add(*fitStat); 00300 // and of course add it to the checkpoint 00301 checkpoint->add(*fitSnapshot); 00302 } 00303 00304 #endif 00305 00307 // State savers 00309 00310 // feed the state to state savers 00311 // save state every N generation 00312 eoValueParam<unsigned>& saveFrequencyParam = _parser.createParam(unsigned(0), "saveFrequency", "Save every F generation (0 = only final state, absent = never)", '\0', "Persistence" ); 00313 00314 if (_parser.isItThere(saveFrequencyParam)) 00315 { 00316 // first make sure dirName is OK 00317 if (! dirOK ) 00318 dirOK = testDirRes(dirNameParam.value(), eraseParam.value()); // TRUE 00319 00320 unsigned freq = (saveFrequencyParam.value()>0 ? saveFrequencyParam.value() : UINT_MAX ); 00321 #ifdef _MSVC 00322 std::string stmp = dirNameParam.value() + "\generations"; 00323 #else 00324 std::string stmp = dirNameParam.value() + "/generations"; 00325 #endif 00326 eoCountedStateSaver *stateSaver1 = new eoCountedStateSaver(freq, _state, stmp); 00327 _state.storeFunctor(stateSaver1); 00328 checkpoint->add(*stateSaver1); 00329 } 00330 00331 // save state every T seconds 00332 eoValueParam<unsigned>& saveTimeIntervalParam = _parser.createParam(unsigned(0), "saveTimeInterval", "Save every T seconds (0 or absent = never)", '\0',"Persistence" ); 00333 if (_parser.isItThere(saveTimeIntervalParam) && saveTimeIntervalParam.value()>0) 00334 { 00335 // first make sure dirName is OK 00336 if (! dirOK ) 00337 dirOK = testDirRes(dirNameParam.value(), eraseParam.value()); // TRUE 00338 00339 #ifdef _MSVC 00340 std::string stmp = dirNameParam.value() + "\time"; 00341 #else 00342 std::string stmp = dirNameParam.value() + "/time"; 00343 #endif 00344 eoTimedStateSaver *stateSaver2 = new eoTimedStateSaver(saveTimeIntervalParam.value(), _state, stmp); 00345 _state.storeFunctor(stateSaver2); 00346 checkpoint->add(*stateSaver2); 00347 } 00348 00349 // and that's it for the (control and) output 00350 return *checkpoint; 00351 } 00352 00353 #endif