diff --git a/eo/src/do/Readme b/eo/src/do/Readme new file mode 100644 index 000000000..70b1d9c00 --- /dev/null +++ b/eo/src/do/Readme @@ -0,0 +1,33 @@ +This directory contains templatized code that is supposed to be +instanciated and compiled in an actual library for every type of EOType + +The user can then modify and recompile only the part he/she wishes to +change (as in any library!). + +See in EO src/ga dir the corresponding .cpp files, that simply instanciate +the functions here for eoBit AND eoBit +and in EO test dir the t-eoGA.cpp file that is a sample program that uses +the whole facility. + +All make_XXX.h file define some parser-based constructions of basic +Evolutionary Algorithms components, using state-based memory management +(see in src/utils dir, or read the tutorial). + +In this src/do dir, the following ***representation indedendent*** code +is defined + +make_algo_scalar.h The selection/replacement for scalar fitnesses +make_checkpoint.h The output facilities +make_continue.h The stpping criteria +make_help.cpp Help on demand (+ status file) +make_pop.h Init of the population (from an EOT initializer) +make_run.h Run the algorithm + +Note: +two additional make_XXX.h files need to be defined for each representation + +make_genotype.h Builds an initializer for the corresponding EOType +make_op.h Builds a general Operator to be used in the algo + +MS, April 23, 2001 + diff --git a/eo/src/do/make_algo_scalar.h b/eo/src/do/make_algo_scalar.h new file mode 100644 index 000000000..34949dbc6 --- /dev/null +++ b/eo/src/do/make_algo_scalar.h @@ -0,0 +1,186 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// make_algo_scalar.h +// (c) Maarten Keijzer, Marc Schoenauer 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 + */ +//----------------------------------------------------------------------------- + +#ifndef _make_run_h +#define _make_run_h + +#include // for eo_is_a_rate +// everything tha's needed for the algorithms - SCALAR fitness + +// Selection +// the eoSelectOne's +#include // also contains the eoSequentialSelect +#include +#include +#include +#include +#include + +// Breeders +#include + +// Replacement +// #include +#include +#include +#include + +// Algorithm (only this one needed) +#include + + // also need the parser and param includes +#include +#include + + +/* + * This function builds the algorithm (i.e. selection and replacement) + * from existing continue (or checkpoint) and operators + * + * It uses a parser (to get user parameters) and a state (to store the memory) + * the last argument is an individual, needed for 2 reasons + * it disambiguates the call after instanciations + * some operator might need some private information about the indis + * + * This is why the template is the complete EOT even though only the fitness + * is actually templatized here +*/ + +template +eoAlgo & do_make_algo_scalar(eoParameterLoader& _parser, eoState& _state, eoEvalFunc& _eval, eoContinue& _ccontinue, eoGenOp& _op) +{ + // the selection + eoValueParam& selectionParam = _parser.createParam(eoParamParamType("DetTour(2)"), "selection", "Selection: Roulette, DetTour(T), StochTour(t) or Sequential(ordered/unordered)", 'S', "engine"); + + eoParamParamType & ppSelect = selectionParam.value(); // pair > + + eoSelectOne* select ; + if (ppSelect.first == string("DetTour")) + { + unsigned size; + istrstream is(ppSelect.second[0].c_str()); // size of det tournament + is >> size; + select = new eoDetTournamentSelect(size); + } + else if (ppSelect.first == string("StochTour")) + { + double p; + istrstream is(ppSelect.second[0].c_str()); // proba of binary tournament + is >> p; + select = new eoStochTournamentSelect(p); + } + else if (ppSelect.first == string("Sequential")) // one after the other + { + if (ppSelect.second.size() == 0) // no argument -> default = ordered + select = new eoSequentialSelect; + else + { + bool b; + istrstream is(ppSelect.second[0].c_str()); + is >> b; + select = new eoStochTournamentSelect(b); + } + } + else if (ppSelect.first == string("Roulette")) // no argument (yet) + { + select = new eoProportionalSelect; + } + else + throw runtime_error("Invalid selection"); + + _state.storeFunctor(select); + + // the number of offspring + eoValueParam& offspringRateParam = _parser.createParam(eoRateParamType("100%"), "offspringRate", "Nb of offspring (percentage or absolute)", 'O', "engine"); + // an eoRateParamType is simply a pair + double offRate=offspringRateParam.value().first; + bool offInterpret_as_rate = offspringRateParam.value().second; + + // the replacement + eoValueParam& replacementParam = _parser.createParam(eoParamParamType("Comma"), "replacement", "Replacement: Comma, Plus or EPTour(T)", 'R', "engine"); + + eoParamParamType & ppReplace = replacementParam.value(); // pair > + + eoReplacement* replace ; + if (ppReplace.first == string("Comma")) // Comma == generational + { + replace = new eoCommaReplacement; + } + else if (ppReplace.first == string("Plus")) + { + replace = new eoPlusReplacement; + } + else if (ppReplace.first == string("EPTour")) + { + unsigned size; + istrstream is(ppReplace.second[0].c_str()); // size of EP tournament + is >> size; + replace = new eoEPReplacement(size); + } + else if (ppReplace.first == string("SSGAWorse")) + { + replace = new eoSSGAWorseReplacement; + } + else if (ppReplace.first == string("SSGADet")) + { + unsigned size; + istrstream is(ppReplace.second[0].c_str()); // size of Det. tournament + is >> size; + replace = new eoSSGADetTournamentReplacement(size); + } + else if (ppReplace.first == string("SSGAStoch")) + { + double p; + istrstream is(ppReplace.second[0].c_str()); // proba of binary tournament + is >> p; + replace = new eoSSGAStochTournamentReplacement(p); + } + else + throw runtime_error("Invalid replacement"); + + _state.storeFunctor(replace); + + // adding weak elitism + eoValueParam& weakElitismParam = _parser.createParam(false, "weakElitism", "Old best parent replaces new worst offspring *if necessary*", 'w', "engine"); + if (weakElitismParam.value()) + { + eoReplacement *replaceTmp = replace; + replace = new eoWeakElitistReplacement(*replaceTmp); + _state.storeFunctor(replace); + } + + // the general breeder + eoGeneralBreeder *breed = + new eoGeneralBreeder(*select, _op, offRate, offInterpret_as_rate); + _state.storeFunctor(breed); + // now the eoEasyEA + eoAlgo *algo = new eoEasyEA(_ccontinue, _eval, *breed, *replace); + _state.storeFunctor(algo); + // that's it! + return *algo; +} + +#endif diff --git a/eo/src/do/make_checkpoint.h b/eo/src/do/make_checkpoint.h new file mode 100644 index 000000000..0efd02b37 --- /dev/null +++ b/eo/src/do/make_checkpoint.h @@ -0,0 +1,269 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// make_checkpoint.h +// (c) Maarten Keijzer, Marc Schoenauer and GeNeura Team, 2000 +/* + 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 + */ +//----------------------------------------------------------------------------- + +#ifndef _make_checkpoint_h +#define _make_checkpoint_h + +#include +#include // for minimizing_fitness() +#include +#include +#include + +/////////////////// The checkpoint and other I/O ////////////// + + +template +eoCheckPoint& do_make_checkpoint(eoParameterLoader& _parser, eoState& _state, eoEvalFuncCounter& _eval, eoContinue& _continue) +{ + // first, create a checkpoint from the eoContinue + eoCheckPoint *checkpoint = new eoCheckPoint(_continue); + _state.storeFunctor(checkpoint); + + /////////////////// + // Counters + ////////////////// + // is nb Eval to be used as counter? + eoValueParam& useEvalParam = _parser.createParam(true, "useEval", "Use nb of eval. as counter (vs nb of gen.)", '\0', "Output"); + + // Create anyway a generation-counter parameter + eoValueParam *generationCounter = new eoValueParam(0, "Gen."); + // Create an incrementor (sub-class of eoUpdater). + eoIncrementor* increment = new eoIncrementor(generationCounter->value()); + // Add it to the checkpoint, + checkpoint->add(*increment); + // and store it in the state + _state.storeFunctor(increment); + + ///////////////////////////////////////// + // now some statistics on the population: + ///////////////////////////////////////// + /** + * existing stats as of today, April 10. 2001 + * + * eoBestFitnessStat : best value in pop - type EOT::Fitness + * eoAverageStat : average value in pop - type EOT::Fitness + * eoSecondMomentStat: average + stdev - type pair + * eoSortedPopStat : whole population - type string (!!) + * eoScalarFitnessStat: the fitnesses - type vector + * eoDFCSTat : FDC wrt best in pop or absolute best - type double + * requires an eoDistance. See eoFDCStat.h + * also computes all elements for the FDC scatter plot + */ + + // Best fitness in population + //--------------------------- + eoValueParam& printBestParam = _parser.createParam(true, "printBestStat", "Print Best/avg/stdev every gen.", '\0', "Output"); + eoValueParam& plotBestParam = _parser.createParam(false, "plotBestStat", "Plot Best/avg Stat", '\0', "Output"); + eoValueParam& bestFileNameParam = _parser.createParam(string("best.xg"), "BestFileName", "Name of file for Best/avg/stdev", '\0', "Output"); + bool fileBestParam = _parser.isItThere(bestFileNameParam); + + eoBestFitnessStat *bestStat = NULL; + if ( printBestParam.value() || plotBestParam.value() || fileBestParam ) + // we need the bestStat for at least one of the 3 above + { + bestStat = new eoBestFitnessStat; + // store it + _state.storeFunctor(bestStat); + // add it to the checkpoint + checkpoint->add(*bestStat); + } + + // Average fitness alone + //---------------------- + eoAverageStat *averageStat = NULL; // do we need averageStat? + if ( plotBestParam.value() ) // we need it for gnuplot output + { + averageStat = new eoAverageStat; + // store it + _state.storeFunctor(averageStat); + // add it to the checkpoint + checkpoint->add(*averageStat); + } + + // Second moment stats: average and stdev + //--------------------------------------- + eoSecondMomentStats *secondStat = NULL; + if ( printBestParam.value() ) // we need it for sreen output + { + secondStat = new eoSecondMomentStats; + // store it + _state.storeFunctor(secondStat); + // add it to the checkpoint + checkpoint->add(*secondStat); + } + + + // Dump of the whole population + //----------------------------- + eoSortedPopStat *popStat = NULL; + eoValueParam& printPopParam = _parser.createParam(false, "printPop", "Print sorted pop. every gen.", '\0', "Output"); + if ( printPopParam.value() ) // we do want pop dump + { + popStat = new eoSortedPopStat("Dump of whole population"); + // store it + _state.storeFunctor(popStat); + // add it to the checkpoint + checkpoint->add(*popStat); + } + + + // the Fitness Distance Correlation + //--------------------------------- + eoValueParam& printFDCParam = _parser.createParam(true, "printFDC", "Print FDC coeff. every gen.", '\0', "Output"); + eoValueParam& plotFDCParam = _parser.createParam(false, "plotFDCStat", "Plot FDC scatter plot", '\0', "Output"); + + eoFDCStat *fdcStat = NULL; + if ( printFDCParam.value() || plotFDCParam.value() ) // we need FDCStat + { + // need first an object to compute the distances - here Hamming dist. + eoQuadDistance *dist = new eoQuadDistance; + _state.storeFunctor(dist); + fdcStat = new eoFDCStat(*dist); + // storeFunctor it + _state.storeFunctor(fdcStat); + // add it to the checkpoint + checkpoint->add(*fdcStat); + } + + /////////////// + // The monitors + /////////////// + // do we want an eoStdoutMonitor? + bool needStdoutMonitor = printBestParam.value() || printFDCParam.value() + || printPopParam.value() ; + + // The Stdout monitor will print parameters to the screen ... + if ( needStdoutMonitor ) + { + eoStdoutMonitor *monitor = new eoStdoutMonitor(false); + _state.storeFunctor(monitor); + + // when called by the checkpoint (i.e. at every generation) + checkpoint->add(*monitor); + + // the monitor will output a series of parameters: add them + monitor->add(*generationCounter); + if (useEvalParam.value()) // we want nb of evaluations + monitor->add(_eval); + if (printBestParam.value()) + { + monitor->add(*bestStat); + monitor->add(*secondStat); + } + if (printFDCParam.value()) + monitor->add(*fdcStat); + if ( printPopParam.value()) + monitor->add(*popStat); + } + + if (fileBestParam) // A file monitor for best & secondMoment + { + eoFileMonitor *fileMonitor = new eoFileMonitor(bestFileNameParam.value()); + // save and give to checkpoint + _state.storeFunctor(fileMonitor); + checkpoint->add(*fileMonitor); + // and feed with some statistics + fileMonitor->add(*generationCounter); + fileMonitor->add(_eval); + fileMonitor->add(*bestStat); + fileMonitor->add(*secondStat); + } + + if (plotBestParam.value()) // an eoGnuplot1DMonitor for best & average + { + eoGnuplot1DMonitor *gnuMonitor = new eoGnuplot1DMonitor("_gnu_best.xg",minimizing_fitness()); + // save and give to checkpoint + _state.storeFunctor(gnuMonitor); + checkpoint->add(*gnuMonitor); + // and feed with some statistics + if (useEvalParam.value()) + gnuMonitor->add(_eval); + else + gnuMonitor->add(*generationCounter); + gnuMonitor->add(*bestStat); + gnuMonitor->add(*averageStat); + } + + if (plotFDCParam.value()) // a specific plot monitor for FDC + { + // first into a file (it adds everything ti itself + eoFDCFileSnapshot *fdcFileSnapshot = new eoFDCFileSnapshot(*fdcStat); + _state.storeFunctor(fdcFileSnapshot); + // then to a Gnuplot monitor + eoGnuplot1DSnapshot *fdcGnuplot = new eoGnuplot1DSnapshot(*fdcFileSnapshot); + _state.storeFunctor(fdcGnuplot); + + // and of course add them to the checkPoint + checkpoint->add(*fdcFileSnapshot); + checkpoint->add(*fdcGnuplot); + } + + eoValueParam plotHistogramParam = _parser.createParam(false, "plotHisto", "Plot histogram of fitnesses", '\0', "Output"); + if (plotHistogramParam.value()) // want to see how the fitness is spread? + { + eoScalarFitnessStat *fitStat = new eoScalarFitnessStat; + _state.storeFunctor(fitStat); + checkpoint->add(*fitStat); + // a gnuplot-based monitor for snapshots: needs a dir name + eoGnuplot1DSnapshot *fitSnapshot = new eoGnuplot1DSnapshot("Fitnesses"); + _state.storeFunctor(fitSnapshot); + // add any stat that is a vector to it + fitSnapshot->add(*fitStat); + // and of course add it to the checkpoint + checkpoint->add(*fitSnapshot); + } + + ////////////////////////////////// + // State savers + ////////////////////////////// + + // feed the state to state savers + // save state every N generation + eoValueParam& saveFrequencyParam = _parser.createParam(unsigned(0), "saveFrequency", "Save every F generation (0 = only final state, absent = never)", '\0', "Persistence" ); + + if (_parser.isItThere(saveFrequencyParam)) + { + unsigned freq = (saveFrequencyParam.value()>0 ? saveFrequencyParam.value() : UINT_MAX ); + eoCountedStateSaver *stateSaver1 = new eoCountedStateSaver(freq, _state, "generation"); + _state.storeFunctor(stateSaver1); + checkpoint->add(*stateSaver1); + } + + // save state every T seconds + eoValueParam& saveTimeIntervalParam = _parser.createParam(unsigned(0), "saveTimeInterval", "Save every T seconds (0 or absent = never)", '\0',"Persistence" ); + if (_parser.isItThere(saveTimeIntervalParam) && saveTimeIntervalParam.value()>0) + { + eoTimedStateSaver *stateSaver2 = new eoTimedStateSaver(saveTimeIntervalParam.value(), _state, "time"); + _state.storeFunctor(stateSaver2); + checkpoint->add(*stateSaver2); + } + + // and that's it for the (control and) output + return *checkpoint; +} + +#endif diff --git a/eo/src/do/make_continue.h b/eo/src/do/make_continue.h new file mode 100644 index 000000000..cda5d9a21 --- /dev/null +++ b/eo/src/do/make_continue.h @@ -0,0 +1,157 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// make_continue.h +// (c) Maarten Keijzer, Marc Schoenauer and GeNeura Team, 2000 +/* + 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 + */ +//----------------------------------------------------------------------------- + +#ifndef _make_continue_h +#define _make_continue_h + +/* +Contains the templatized version of parser-based choice of stopping criterion +It can then be instantiated, and compiled on its own for a given EOType +(see e.g. in dir ga, ga.cpp) +*/ + +// Continuators - all include eoContinue.h +#include +#include +#include +#include +#include +#ifndef _MSC_VER +#include // CtrlC handling (using 2 global variables!) +#endif + + // also need the parser and param includes +#include +#include + + +/////////////////// the stopping criterion //////////////// +template +eoCombinedContinue * make_combinedContinue(eoCombinedContinue *_combined, eoContinue *_cont) +{ + if (_combined) // already exists + _combined->add(*_cont); + else + _combined = new eoCombinedContinue(*_cont); + return _combined; +} + +template +eoContinue & do_make_continue(eoParameterLoader& _parser, eoState& _state, eoEvalFuncCounter & _eval) +{ + //////////// Stopping criterion /////////////////// + // the combined continue - to be filled + eoCombinedContinue *continuator = NULL; + + // for each possible criterion, check if wanted, otherwise do nothing + + // First the eoGenContinue - need a default value so you can run blind + // but we also need to be able to avoid it <--> 0 + eoValueParam& maxGenParam = _parser.createParam(unsigned(100), "maxGen", "Maximum number of generations () = none)",'G',"Stopping criterion"); + + if (maxGenParam.value()) // positive: -> define and store + { + eoGenContinue *genCont = new eoGenContinue(maxGenParam.value()); + _state.storeFunctor(genCont); + // and "add" to combined + continuator = make_combinedContinue(continuator, genCont); + } + + // the steadyGen continue - only if user imput + eoValueParam& steadyGenParam = _parser.createParam(unsigned(100), "steadyGen", "Number of generations with no improvement",'s', "Stopping criterion"); + eoValueParam& minGenParam = _parser.createParam(unsigned(0), "minGen", "Minimum number of generations",'g', "Stopping criterion"); + if (_parser.isItThere(steadyGenParam)) + { + eoSteadyGenContinue *steadyCont = new eoSteadyGenContinue + (minGenParam.value(), steadyGenParam.value()); + // store + _state.storeFunctor(steadyCont); + // add to combinedContinue + continuator = make_combinedContinue(continuator, steadyCont); + } + + // Same thing with Eval - but here default value is 0 + eoValueParam& maxEvalParam = _parser.createParam(unsigned(0), "maxEval", "Maximum number of evaluations (0 = none)",'E',"Stopping criterion"); + + if (maxEvalParam.value()) // positive: -> define and store + { + eoEvalContinue *evalCont = new eoEvalContinue(_eval, maxEvalParam.value()); + _state.storeFunctor(evalCont); + // and "add" to combined + continuator = make_combinedContinue(continuator, evalCont); + } + /* + // the steadyEval continue - only if user imput + eoValueParam& steadyGenParam = _parser.createParam(unsigned(100), "steadyGen", "Number of generations with no improvement",'s', "Stopping criterion"); + eoValueParam& minGenParam = _parser.createParam(unsigned(0), "minGen", "Minimum number of generations",'g', "Stopping criterion"); + if (_parser.isItThere(steadyGenParam)) + { + eoSteadyGenContinue *steadyCont = new eoSteadyFitContinue + (minGenParam.value(), steadyGenParam.value()); + // store + _state.storeFunctor(steadyCont); + // add to combinedContinue + continuator = make_combinedContinue(continuator, steadyCont); + } + */ + // the target fitness + eoFitContinue *fitCont; + eoValueParam& targetFitnessParam = _parser.createParam(double(0.0), "targetFitness", "Stop when fitness reaches",'T', "Stopping criterion"); + if (_parser.isItThere(targetFitnessParam)) + { + fitCont = new eoFitContinue + (targetFitnessParam.value()); + // store + _state.storeFunctor(fitCont); + // add to combinedContinue + continuator = make_combinedContinue(continuator, fitCont); + } + +#ifndef _MSC_VER + // the CtrlC interception (Linux only I'm afraid) + eoCtrlCContinue *ctrlCCont; + eoValueParam& ctrlCParam = _parser.createParam(false, "CtrlC", "Terminate current generation upon Ctrl C",'C', "Stopping criterion"); + if (_parser.isItThere(ctrlCParam)) + { + ctrlCCont = new eoCtrlCContinue; + // store + _state.storeFunctor(ctrlCCont); + // add to combinedContinue + continuator = make_combinedContinue(continuator, ctrlCCont); + } +#endif + + // now check that there is at least one! + if (!continuator) + throw runtime_error("You MUST provide a stopping criterion"); + // OK, it's there: store in the eoState + _state.storeFunctor(continuator); + + // and return + return *continuator; +} + +#endif diff --git a/eo/src/do/make_help.cpp b/eo/src/do/make_help.cpp new file mode 100644 index 000000000..31cb749f6 --- /dev/null +++ b/eo/src/do/make_help.cpp @@ -0,0 +1,54 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// make_help.h +// (c) Maarten Keijzer, Marc Schoenauer 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 + */ +//----------------------------------------------------------------------------- +#include +#include + +/** Generation of the status file, and output of the help message if needed + * + * MUST be called after ALL parameters have been read in order to list them + * + * Warning: this is a plain .cpp file and shoudl NOT be included anywhere, + * but compiled separately and stored in a library. + */ +void make_help(eoParser & _parser) +{ + // name of the "status" file where all actual parameter values will be saved + string str_status = _parser.ProgramName() + ".status"; // default value + eoValueParam& statusParam = _parser.createParam(str_status, "status","Status file",'\0', "Persistence" ); + + // do the following AFTER ALL PARAMETERS HAVE BEEN PROCESSED + // i.e. in case you need parameters somewhere else, postpone these + if (_parser.userNeedsHelp()) + { + _parser.printHelp(cout); + exit(1); + } + if (statusParam.value() != "") + { + ofstream os(statusParam.value().c_str()); + os << _parser; // and you can use that file as parameter file + } +} diff --git a/eo/src/do/make_pop.h b/eo/src/do/make_pop.h new file mode 100644 index 000000000..2ab383094 --- /dev/null +++ b/eo/src/do/make_pop.h @@ -0,0 +1,97 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// make_pop.h +// (c) Maarten Keijzer, Marc Schoenauer 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 + */ +//----------------------------------------------------------------------------- + +#ifndef _make_pop_h +#define _make_pop_h + +#include +#include +#include +#include +#include + + +///////////////////////////////// INIT POP /////////////////////////////// +/** + * Templatized version of parser-based construct of the population + * + other initializations that are NOT representation-dependent. + * + * It must then be instantiated, and compiled on its own for a given EOType + * (see e.g. ga.h and ga.pp in dir ga) +*/ + + +template +eoPop& do_make_pop(eoParser & _parser, eoState& _state, eoInit & _init) +{ + eoValueParam& seedParam = _parser.createParam(uint32(time(0)), "seed", "Random number seed", 'S'); + eoValueParam& popSize = _parser.createParam(unsigned(20), "PopSize", "Population Size", 'P', "initialization"); + + // Either load or initialize + // create an empty pop and let the state handle the memory + eoPop& pop = _state.takeOwnership(eoPop()); + + eoValueParam& loadNameParam = _parser.createParam(string(""), "Load","A save file to restart from",'L', "Persistence" ); + eoValueParam & recomputeFitnessParam = _parser.createParam(false, "recomputeFitness", "Recompute the fitness after re-loading the pop.?", 'r', "Persistence" ); + + if (loadNameParam.value() != "") // something to load + { + // create another state for reading + eoState inState; // a state for loading - WITHOUT the parser + // register the rng and the pop in the state, so they can be loaded, + // and the present run will be the exact continuation of the saved run + // eventually with different parameters + inState.registerObject(pop); + inState.registerObject(rng); + inState.load(loadNameParam.value()); // load the pop and the rng + // the fitness is read in the file: + // do only evaluate the pop if the fitness has changed + if (recomputeFitnessParam.value()) + { + for (unsigned i=0; i + +/* + * A trivial function - only here to allow instanciation with a give EOType + * and separate compilation - see in ga dir, make_run_ga + * +*/ + +template +void do_run(eoAlgo& _algo, eoPop& _pop) +{ + _algo(_pop); +} + +#endif diff --git a/eo/src/eo b/eo/src/eo index 3b7c78b69..0ac3bda36 100644 --- a/eo/src/eo +++ b/eo/src/eo @@ -67,7 +67,9 @@ // Continuators - all include eoContinue.h #include #include +#include #include +#include #include #ifndef _MSC_VER #include // CtrlC handling (using 2 global variables!) diff --git a/eo/src/eoEasyEA.h b/eo/src/eoEasyEA.h index d28f62af5..c762b8ee0 100644 --- a/eo/src/eoEasyEA.h +++ b/eo/src/eoEasyEA.h @@ -29,6 +29,7 @@ #include #include +#include #include #include #include diff --git a/eo/src/eoEvalFunc.h b/eo/src/eoEvalFunc.h index 9451e66f1..73a27bac7 100644 --- a/eo/src/eoEvalFunc.h +++ b/eo/src/eoEvalFunc.h @@ -44,30 +44,4 @@ template class eoEvalFunc : public eoUF typedef typename EOT::Fitness EOFitT; }; -/** -Counts the number of evaluations actually performed, thus checks first -if it has to evaluate.. etc. -*/ - -#include -template class eoEvalFuncCounter : public eoEvalFunc, public eoValueParam -{ - public : - eoEvalFuncCounter(eoEvalFunc& _func, std::string _name = "Eval. ") - : eoValueParam(0, _name), func(_func) {} - - virtual void operator()(EOT& _eo) - { - if (_eo.invalid()) - { - value()++; - func(_eo); - } - } - - private : - eoEvalFunc& func; -}; - - #endif diff --git a/eo/src/eoReduce.h b/eo/src/eoReduce.h index a653f8ef2..4c0ff77c3 100644 --- a/eo/src/eoReduce.h +++ b/eo/src/eoReduce.h @@ -89,7 +89,8 @@ typedef typename EOT::Fitness Fitness; t_size(_t_size) { if (t_size < 2) - { // warning, error? + { + cout << "Warning: EP tournament size should be >= 2. Adjusted" << endl; t_size = 2; } } diff --git a/eo/src/eoVariableLengthMutation.h b/eo/src/eoVariableLengthMutation.h index 2a2d87d35..b9c089f48 100644 --- a/eo/src/eoVariableLengthMutation.h +++ b/eo/src/eoVariableLengthMutation.h @@ -21,7 +21,7 @@ Contact: todos@geneura.ugr.es, http://geneura.ugr.es Marc.Schoenauer@polytechnique.fr mak@dhi.dk - CVS Info: $Date: 2001-03-21 13:09:47 $ $Version$ $Author: jmerelo $ + CVS Info: $Date: 2001-04-24 04:52:04 $ $Version$ $Author: evomarc $ */ //----------------------------------------------------------------------------- @@ -187,19 +187,23 @@ public : /** ctor with an external gene chooser - * @param nMin min number of atoms t oleave in the individual + * @param nMin min number of atoms to leave in the individual * @param _geneChooser an eoGeneCHooser to choose which one to delete */ eoVlDelMutation(unsigned _nMin, eoGeneDelChooser & _chooser) : nMin(_nMin), uChooser(), chooser(_chooser) {} - /** ctor with unifirm gebe chooser + /** ctor with uniform gene chooser - * @param nMin min number of atoms t oleave in the individual + * @param nMin min number of atoms to leave in the individual */ eoVlDelMutation(unsigned _nMin) : nMin(_nMin), uChooser(), chooser(uChooser) {} + /** Do the job (delete one gene) + + * @param _eo the EO to mutate + */ bool operator()(EOT & _eo) { if (_eo.size() <= nMin) diff --git a/eo/src/ga/Makefile.am b/eo/src/ga/Makefile.am index 38d1695c5..7bf8a6c69 100644 --- a/eo/src/ga/Makefile.am +++ b/eo/src/ga/Makefile.am @@ -6,7 +6,14 @@ INCLUDES = -I$(top_builddir)/src lib_LIBRARIES = libga.a -libga_a_SOURCES = ga.cpp +libga_a_SOURCES = make_algo_scalar_ga.cpp \ + make_checkpoint_ga.cpp \ + make_continue_ga.cpp \ + make_genotype_ga.cpp \ + make_help.cpp \ + make_op_ga.cpp \ + make_pop_ga.cpp \ + make_run_ga.cpp CPPFLAGS = -O2 -Wall diff --git a/eo/src/ga/Readme b/eo/src/ga/Readme new file mode 100644 index 000000000..69d7d4660 --- /dev/null +++ b/eo/src/ga/Readme @@ -0,0 +1,21 @@ +This directory contains: + +- some standard EO source files, named eoXXXXX, that define objects +for the eoBit representation (bitstrings). + +- some make_XXX.cpp files that are instanciations for EO bitstrings +(eoBit AND eoBit) of the tempatized code +that is defined in the EO src/do dir. +This MK's trick allows to actually compile all these bits in a library +(eolibga.a) and to only recompile the bits you need for your own +(bitstring!) application. +@see src/do/make_XXX.h files, and test/t-eoGA.cpp for an example use. + +Note: +Also are *defined* here two representation dependent make_XXX.h files +(together with their instanciations in make_XXX.cpp), namely the ones +that constructs the EOType initializer (make_genotype.h) and the one +that buils up the operators (make_op.h). + +MS, April 23, 2001CVS + diff --git a/eo/src/ga/ga.cpp b/eo/src/ga/ga.cpp deleted file mode 100644 index be17928b2..000000000 --- a/eo/src/ga/ga.cpp +++ /dev/null @@ -1,91 +0,0 @@ -#include -#include - -eoValueParam xoverRate(0.6f, "xoverrate", "The crossover rate", 'x'); -eoValueParam mutRate(1.0f, "mutationrate", "The mutation rate", 'm'); -eoValueParam chromSize(unsigned(10), "chromosomeSize", "The length of the bitstrings", 'n'); -eoValueParam popSize(unsigned(20), "PopSize", "Population Size", 'P'); - -template -eoAlgo >& do_make_ga(eoParameterLoader& _parser, eoEvalFunc >& _eval, eoCheckPoint >& _checkpoint, eoState& _state) -{ - typedef eoBit EOT; - - _parser.processParam(xoverRate, "genetics"); - _parser.processParam(mutRate, "genetics"); - _parser.processParam(chromSize, "initialization"); - - eoBitMutation* mutOp = new eoBitMutation(1. / float(chromSize.value())); - _state.storeFunctor(mutOp); - - eo1PtBitXover* crossOp = new eo1PtBitXover; - _state.storeFunctor(crossOp); - - eoSelectOne* select = new eoDetTournamentSelect(2); - _state.storeFunctor(select); - - eoSGA >* sga = new eoSGA(*select, *crossOp, xoverRate.value(), *mutOp, mutRate.value(), _eval, _checkpoint); - _state.storeFunctor(sga); - return *sga; -} - -template -eoPop >& do_init_ga(eoParameterLoader& _parser, eoState& _state, FitT) -{ - typedef eoBit EOT; - - _parser.processParam(chromSize, "initialization"); - _parser.processParam(popSize, "initialization"); - - eoBooleanGenerator gen; - eoInitFixedLength init(chromSize.value(), gen); - - // Let the state handle the memory - eoPop& pop = _state.takeOwnership(eoPop()); - - _state.registerObject(pop); - - // initialize the population - - pop.append(popSize.value(), init); - - return pop; -} - -template -void do_run_ga(eoAlgo >& _ga, eoPop >& _pop) -{ - _ga(_pop); -} - -/// The following function merely call the templatized do_* functions above - -eoAlgo >& make_ga(eoParameterLoader& _parser, eoEvalFunc >& _eval, eoCheckPoint >& _checkpoint, eoState& _state) -{ - return do_make_ga(_parser, _eval, _checkpoint, _state); -} - -eoAlgo >& make_ga(eoParameterLoader& _parser, eoEvalFunc >& _eval, eoCheckPoint >& _checkpoint, eoState& _state) -{ - return do_make_ga(_parser, _eval, _checkpoint, _state); -} - -eoPop >& init_ga(eoParameterLoader& _parser, eoState& _state, double _d) -{ - return do_init_ga(_parser, _state, _d); -} - -eoPop >& init_ga(eoParameterLoader& _parser, eoState& _state, eoMinimizingFitness _d) -{ - return do_init_ga(_parser, _state, _d); -} - -void run_ga(eoAlgo >& _ga, eoPop >& _pop) -{ - do_run_ga(_ga, _pop); -} - -void run_ga(eoAlgo >& _ga, eoPop >& _pop) -{ - do_run_ga(_ga, _pop); -} diff --git a/eo/src/ga/ga.h b/eo/src/ga/ga.h index 7a829f54c..244a3050f 100644 --- a/eo/src/ga/ga.h +++ b/eo/src/ga/ga.h @@ -1,24 +1,92 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// ga.h +// (c) Maarten Keijzer, Marc Schoenauer 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 + */ +//----------------------------------------------------------------------------- + +/** This file contains all ***INSTANCIATED*** declarations of all components + * of the library for ***BISTRING*** evolution inside EO. + * It should be included in the file that calls any of the corresponding fns + * + * The corresponding ***INSTANCIATED*** definitions are contained in ga.cpp + * while the TEMPLATIZED code is define in the different makeXXX.h files + * + * Unlike most EO .h files, it does not (and should not) contain any code, + * just declarations + */ + #ifndef ga_h #define ga_h #include #include #include -#include +#include #include +#include #include #include -#include + +//Representation dependent - rewrite everything anew for each representation +////////////////////////// + +// the genotypes +eoInit > & make_genotype(eoParameterLoader& _parser, eoState& _state, double _d); + eoInit > & make_genotype(eoParameterLoader& _parser, eoState& _state, eoMinimizingFitness _d); + +// the operators +eoGenOp >& make_op(eoParameterLoader& _parser, eoState& _state, eoInit >& _init); +eoGenOp >& make_op(eoParameterLoader& _parser, eoState& _state, eoInit >& _init); + +//Representation INdependent +//////////////////////////// +// if you use your own representation, simply change the types of templates + +// init pop +eoPop >& make_pop(eoParser& _parser, eoState& _state, eoInit >&); +eoPop >& make_ga(eoParser& _parser, eoState& _state, eoInit >&); + +// the continue's +eoContinue >& make_continue(eoParser& _parser, eoState& _state, eoEvalFuncCounter > & _eval); +eoContinue >& make_continue(eoParser& _parser, eoState& _state, eoEvalFuncCounter > & _eval); + +// the checkpoint +eoCheckPoint >& make_checkpoint(eoParameterLoader& _parser, eoState& _state, eoEvalFuncCounter >& _eval, eoContinue >& _continue); +eoCheckPoint >& make_checkpoint(eoParameterLoader& _parser, eoState& _state, eoEvalFuncCounter >& _eval, eoContinue >& _continue); -eoAlgo >& make_ga(eoParameterLoader& _parser, eoEvalFunc >& _eval, eoCheckPoint >& _checkpoint, eoState& state); -eoAlgo >& make_ga(eoParameterLoader& _parser, eoEvalFunc >& _eval, eoCheckPoint >& _checkpoint, eoState& state); +// the algo +eoAlgo >& make_algo_scalar(eoParameterLoader& _parser, eoState& _state, eoEvalFunc >& _eval, eoContinue >& _ccontinue, eoGenOp >& _op); -eoPop >& init_ga(eoParameterLoader& _parser, eoState& _state, double); -eoPop >& init_ga(eoParameterLoader& _parser, eoState& _state, eoMinimizingFitness); +eoAlgo >& make_algo_scalar(eoParameterLoader& _parser, eoState& _state, eoEvalFunc >& _eval, eoContinue >& _ccontinue, eoGenOp >& _op); -void run_ga(eoAlgo >& _ga, eoPop >& _pop); -void run_ga(eoAlgo >& _ga, eoPop >& _pop); +// run +void run_ea(eoAlgo >& _ga, eoPop >& _pop); +void run_ea(eoAlgo >& _ga, eoPop >& _pop); + +// end of parameter input (+ .status + help) +// that one is not templatized, but is here for the sake of completeness +void make_help(eoParser & _parser); #endif diff --git a/eo/src/ga/make_algo_scalar_ga.cpp b/eo/src/ga/make_algo_scalar_ga.cpp new file mode 100644 index 000000000..c3bbaba4c --- /dev/null +++ b/eo/src/ga/make_algo_scalar_ga.cpp @@ -0,0 +1,59 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// make_algo_scalar_ga.cpp +// (c) Maarten Keijzer, Marc Schoenauer 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 + */ +//----------------------------------------------------------------------------- + +/** This file contains all ***INSTANCIATED DEFINITIONS*** of operators + * of the library for ***BISTRING*** evolution inside EO. + * It should be included in the file that calls any of the corresponding fns + * Compiling this file allows one to generate part of the library (i.e. object + * files that you just need to link with your own main and fitness code). + * + * The corresponding ***INSTANCIATED DECLARATIONS*** are contained + * in make_algo_scalar_ga.h + * while the TEMPLATIZED code is define in make_algo_scalar.h in the do dir + * + * Unlike most EO .h files, it does not (and should not) contain any code, + * just declarations + */ + +// The templatized code +#include +// the instanciating EOType +#include + +/// The following function merely call the templatized do_* functions above + +// Algo +/////// +eoAlgo >& make_algo_scalar(eoParameterLoader& _parser, eoState& _state, eoEvalFunc >& _eval, eoContinue >& _continue, eoGenOp >& _op) +{ + return do_make_algo_scalar(_parser, _state, _eval, _continue, _op); +} + +eoAlgo >& make_algo_scalar(eoParameterLoader& _parser, eoState& _state, eoEvalFunc >& _eval, eoContinue >& _continue, eoGenOp >& _op) +{ + return do_make_algo_scalar(_parser, _state, _eval, _continue, _op); +} + diff --git a/eo/src/ga/make_checkpoint_ga.cpp b/eo/src/ga/make_checkpoint_ga.cpp new file mode 100644 index 000000000..e8e415729 --- /dev/null +++ b/eo/src/ga/make_checkpoint_ga.cpp @@ -0,0 +1,59 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// make_checkpoint_ga.cpp +// (c) Maarten Keijzer, Marc Schoenauer 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 + */ +//----------------------------------------------------------------------------- + +/** This file contains all ***INSTANCIATED DEFINITIONS*** of operators + * of the library for ***BISTRING*** evolution inside EO. + * It should be included in the file that calls any of the corresponding fns + * Compiling this file allows one to generate part of the library (i.e. object + * files that you just need to link with your own main and fitness code). + * + * The corresponding ***INSTANCIATED DECLARATIONS*** are contained + * in make_checkpoint_ga.h + * while the TEMPLATIZED code is define in make_checkpoint.h in the do dir + * + * Unlike most EO .h files, it does not (and should not) contain any code, + * just declarations + */ + +// The templatized code +#include +// the instanciating EOType +#include + +/// The following function merely call the templatized do_* functions + +// checkpoint +///////////// +eoCheckPoint >& make_checkpoint(eoParameterLoader& _parser, eoState& _state, eoEvalFuncCounter >& _eval, eoContinue >& _continue) +{ + return do_make_checkpoint(_parser, _state, _eval, _continue); +} +eoCheckPoint >& make_checkpoint(eoParameterLoader& _parser, eoState& _state, eoEvalFuncCounter >& _eval, eoContinue >& _continue) +{ + return do_make_checkpoint(_parser, _state, _eval, _continue); +} + + diff --git a/eo/src/ga/make_continue_ga.cpp b/eo/src/ga/make_continue_ga.cpp new file mode 100644 index 000000000..09a0aefee --- /dev/null +++ b/eo/src/ga/make_continue_ga.cpp @@ -0,0 +1,59 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// make_continue_ga.cpp +// (c) Maarten Keijzer, Marc Schoenauer 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 + */ +//----------------------------------------------------------------------------- + +/** This file contains all ***INSTANCIATED DEFINITIONS*** of operators + * of the library for ***BISTRING*** evolution inside EO. + * It should be included in the file that calls any of the corresponding fns + * Compiling this file allows one to generate part of the library (i.e. object + * files that you just need to link with your own main and fitness code). + * + * The corresponding ***INSTANCIATED DECLARATIONS*** are contained + * in make_continue_ga.h + * while the TEMPLATIZED code is define in make_contninue.h in the do dir + * + * Unlike most EO .h files, it does not (and should not) contain any code, + * just declarations + */ + +// The templatized code +#include +// the instanciating EOType +#include + +/// The following function merely call the templatized do_* functions above + +// continue +/////////// +eoContinue >& make_continue(eoParser& _parser, eoState& _state, eoEvalFuncCounter > & _eval) +{ + return do_make_continue(_parser, _state, _eval); +} +eoContinue >& make_continue(eoParser& _parser, eoState& _state, eoEvalFuncCounter > & _eval) +{ + return do_make_continue(_parser, _state, _eval); +} + + diff --git a/eo/src/ga/make_genotype_ga.cpp b/eo/src/ga/make_genotype_ga.cpp new file mode 100644 index 000000000..d6ed1b830 --- /dev/null +++ b/eo/src/ga/make_genotype_ga.cpp @@ -0,0 +1,53 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// make_genotype_ga.cpp +// (c) Maarten Keijzer, Marc Schoenauer 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 + */ +//----------------------------------------------------------------------------- + +/** This file contains all ***INSTANCIATED DEFINITIONS*** of operators + * of the library for ***BISTRING*** evolution inside EO. + * It should be included in the file that calls any of the corresponding fns + * Compiling this file allows one to generate part of the library (i.e. object + * files that you just need to link with your own main and fitness code). + * + * The corresponding ***INSTANCIATED DECLARATIONS*** are contained + * in make_genotype_ga.h + * while the TEMPLATIZED code is define in make_genotype.h in the ga dir + * + * Unlike most EO .h files, it does not (and should not) contain any code, + * just declarations + */ + +// the templatized code +#include + +/// The following function merely call the templatized do_* functions above + +eoInit > & make_genotype(eoParameterLoader& _parser, eoState& _state, double _d) +{ + return do_make_genotype(_parser, _state, _d); +} +eoInit > & make_genotype(eoParameterLoader& _parser, eoState& _state, eoMinimizingFitness _d) +{ + return do_make_genotype(_parser, _state, _d); +} diff --git a/eo/src/ga/make_help.cpp b/eo/src/ga/make_help.cpp new file mode 100644 index 000000000..31cb749f6 --- /dev/null +++ b/eo/src/ga/make_help.cpp @@ -0,0 +1,54 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// make_help.h +// (c) Maarten Keijzer, Marc Schoenauer 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 + */ +//----------------------------------------------------------------------------- +#include +#include + +/** Generation of the status file, and output of the help message if needed + * + * MUST be called after ALL parameters have been read in order to list them + * + * Warning: this is a plain .cpp file and shoudl NOT be included anywhere, + * but compiled separately and stored in a library. + */ +void make_help(eoParser & _parser) +{ + // name of the "status" file where all actual parameter values will be saved + string str_status = _parser.ProgramName() + ".status"; // default value + eoValueParam& statusParam = _parser.createParam(str_status, "status","Status file",'\0', "Persistence" ); + + // do the following AFTER ALL PARAMETERS HAVE BEEN PROCESSED + // i.e. in case you need parameters somewhere else, postpone these + if (_parser.userNeedsHelp()) + { + _parser.printHelp(cout); + exit(1); + } + if (statusParam.value() != "") + { + ofstream os(statusParam.value().c_str()); + os << _parser; // and you can use that file as parameter file + } +} diff --git a/eo/src/ga/make_op_ga.cpp b/eo/src/ga/make_op_ga.cpp new file mode 100644 index 000000000..7ee1eb1bf --- /dev/null +++ b/eo/src/ga/make_op_ga.cpp @@ -0,0 +1,57 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// make_op_ga.cpp +// (c) Maarten Keijzer, Marc Schoenauer 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 + */ +//----------------------------------------------------------------------------- + +/** This file contains all ***INSTANCIATED DEFINITIONS*** of operators + * of the library for ***BISTRING*** evolution inside EO. + * It should be included in the file that calls any of the corresponding fns + * Compiling this file allows one to generate part of the library (i.e. object + * files that you just need to link with your own main and fitness code). + * + * The corresponding ***INSTANCIATED DECLARATIONS*** are contained + * in make_op_ga.h + * while the TEMPLATIZED code is define in make_op.h in the ga dir + * + * Unlike most EO .h files, it does not (and should not) contain any code, + * just declarations + */ + +// Templatized code +#include + +/// The following function merely call the templatized do_* functions above + +// oeprators +//////////// +eoGenOp >& make_op(eoParameterLoader& _parser, eoState& _state, eoInit >& _init) +{ + return do_make_op(_parser, _state, _init); +} + +eoGenOp >& make_op(eoParameterLoader& _parser, eoState& _state, eoInit >& _init) +{ + return do_make_op(_parser, _state, _init); +} + diff --git a/eo/src/ga/make_pop_ga.cpp b/eo/src/ga/make_pop_ga.cpp new file mode 100644 index 000000000..a67e37d38 --- /dev/null +++ b/eo/src/ga/make_pop_ga.cpp @@ -0,0 +1,60 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// make_pop_ga.cpp +// (c) Maarten Keijzer, Marc Schoenauer 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 + */ +//----------------------------------------------------------------------------- + +/** This file contains all ***INSTANCIATED DEFINITIONS*** of operators + * of the library for ***BISTRING*** evolution inside EO. + * It should be included in the file that calls any of the corresponding fns + * Compiling this file allows one to generate part of the library (i.e. object + * files that you just need to link with your own main and fitness code). + * + * The corresponding ***INSTANCIATED DECLARATIONS*** are contained + * in make_pop_ga.h + * while the TEMPLATIZED code is define in make_pop.h in the do dir + * + * Unlike most EO .h files, it does not (and should not) contain any code, + * just declarations + */ + +// The templatized code +#include +// the instanciating EOType +#include + +/// The following function merely call the templatized do_* functions above + +// Init POP +/////////// +eoPop >& make_pop(eoParser& _parser, eoState& _state, eoInit > & _init) +{ + return do_make_pop(_parser, _state, _init); +} + +eoPop >& make_pop(eoParser& _parser, eoState& _state, eoInit > & _init) +{ + return do_make_pop(_parser, _state, _init); +} + + diff --git a/eo/src/ga/make_run_ga.cpp b/eo/src/ga/make_run_ga.cpp new file mode 100644 index 000000000..e3d78ea2e --- /dev/null +++ b/eo/src/ga/make_run_ga.cpp @@ -0,0 +1,61 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// make_run_ga.cpp +// (c) Maarten Keijzer, Marc Schoenauer 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 + */ +//----------------------------------------------------------------------------- + +/** This file contains all ***INSTANCIATED DEFINITIONS*** of operators + * of the library for ***BISTRING*** evolution inside EO. + * It should be included in the file that calls any of the corresponding fns + * Compiling this file allows one to generate part of the library (i.e. object + * files that you just need to link with your own main and fitness code). + * + * The corresponding ***INSTANCIATED DECLARATIONS*** are contained + * in make_run_ga.h + * while the TEMPLATIZED code is define in make_run.h in the do dir + * + * Unlike most EO .h files, it does not (and should not) contain any code, + * just declarations + */ + +// The templatized code +#include +// the instanciating EOType +#include +// the instanciating fitnesses +#include + +/// The following function merely call the templatized do_* functions above + +// run +///////// +void run_ea(eoAlgo >& _ga, eoPop >& _pop) +{ + do_run(_ga, _pop); +} + +void run_ea(eoAlgo >& _ga, eoPop >& _pop) +{ + do_run(_ga, _pop); +} + diff --git a/eo/src/utils/eoParam.h b/eo/src/utils/eoParam.h index b611d84db..a30690e3a 100644 --- a/eo/src/utils/eoParam.h +++ b/eo/src/utils/eoParam.h @@ -28,6 +28,7 @@ #define eoParam_h //----------------------------------------------------------------------------- +#include // for floor #include #include #include @@ -296,6 +297,97 @@ void eoValueParam >::setValue(std::string _valu std::copy(std::istream_iterator(is), std::istream_iterator(), repValue.begin()); } +/* ABANDONNED - See class eoRateType below + /////////////////////////////////////// + Specialization for "rate_or_absolute-number" + +typedef std::pair eoRateType; +template <> +std::string eoValueParam::getValue(void) const +{ + std::ostrstream os; + if (repValue.second) + os << 100*repValue.first << "% " << std::ends; + else + os << repValue.first << " " << std::ends; + return os.str(); +} + +template <> +void eoValueParam::setValue(std::string _value) +{ + double rate; + // check for % + bool interpret_as_rate = false; // == no % + size_t pos = _value.find('%'); + if (pos < _value.size()) // found a % + { + interpret_as_rate = true; + _value.resize(pos); // get rid of % + } + std::istrstream is(_value.c_str()); + is >> rate; + repValue.first = (interpret_as_rate ? rate/100 : floor(rate)); + repValue.second = interpret_as_rate; +} +*/ +/** + * A helper class for the parsing of parameters that can be either a rate + * or an absolute value (integer) + * See eoHowMany.h + */ +class eoRateParamType : public std::pair +{ +public: + eoRateParamType(std::pair _p) : std::pair(_p) {} + eoRateParamType(std::string _value) + { + readFrom(_value); + } + + ostream & printOn(ostream & _os) const + { + if (second) + _os << 100*first << "% " << std::ends; + else + _os << first << " " << std::ends; + return _os; + } + + istream & readFrom(istream & _is) + { + string value; + _is >> value; + readFrom(value); + return _is; + } + + void readFrom(std::string _value) + { + double rate; + // check for % + bool interpret_as_rate = false; // == no % + size_t pos = _value.find('%'); + if (pos < _value.size()) // found a % + { + interpret_as_rate = true; + _value.resize(pos); // get rid of % + } + std::istrstream is(_value.c_str()); + is >> rate; + first = (interpret_as_rate ? rate/100 : floor(rate)); + second = interpret_as_rate; + } + + +}; + +// at the moment, the following are defined in eoParser.cpp +ostream & operator<<(ostream & _os, const eoRateParamType & _rate); +istream & operator>>(istream & _is, eoRateParamType & _rate); + + + /*template class eoContainerParam : public eoParam { @@ -319,5 +411,82 @@ private : ContainerType& value; };*/ +/** + * Another helper class for parsing parameters like + * Keyword(arg1, arg2, ...) + * + * It is basically a pair > + * first string is keyword + * the vector contains all arguments (as strings) + * See make_algo.h + */ + +class eoParamParamType : public std::pair > +{ +public: + eoParamParamType(std::string _value) + { + readFrom(_value); + } + + ostream & printOn(ostream & _os) const + { + _os << first; + unsigned narg = second.size(); + if (!narg) + return _os; + + // Here, we do have args + _os << "("; + if (narg == 1) // 1 arg only + { + _os << second[0] << ")" ; + return _os; + } + // and here more than 1 arg + for (unsigned i=0; i> value; + readFrom(value); + return _is; + } + + void readFrom(std::string & _value) + { + second.resize(0); // just in case + size_t pos = _value.find('('); + if (pos >= _value.size()) // no arguments + { + first = _value; + return; + } + // so here we do have arguments + string t = _value.substr(pos+1);// the arguments + _value.resize(pos); + first = _value; // done for the keyword + + // now all arguments + string delim(" (),"); + while ( (pos=t.find_first_not_of(delim)) < t.size()) + { + size_t posEnd = t.find_first_of(delim, pos); + string u(t,pos); + u.resize(posEnd-pos); + second.push_back(u); + t = t.substr(posEnd); + } + } +}; + +// at the moment, the following are defined in eoParser.cpp +ostream & operator<<(ostream & _os, const eoParamParamType & _rate); +istream & operator>>(istream & _is, eoParamParamType & _rate); #endif diff --git a/eo/src/utils/eoParser.cpp b/eo/src/utils/eoParser.cpp index 451da162d..6c64ac915 100644 --- a/eo/src/utils/eoParser.cpp +++ b/eo/src/utils/eoParser.cpp @@ -351,3 +351,29 @@ bool eoParser::userNeedsHelp(void) return needHelp.value() || !messages.empty(); } + +///////////////// I put these here at the moment +ostream & operator<<(ostream & _os, const eoRateParamType & _rate) +{ + _rate.printOn(_os); + return _os; +} + +istream & operator>>(istream & _is, eoRateParamType & _rate) +{ + _rate.readFrom(_is); + return _is; +} + +ostream & operator<<(ostream & _os, const eoParamParamType & _rate) +{ + _rate.printOn(_os); + return _os; +} + +istream & operator>>(istream & _is, eoParamParamType & _rate) +{ + _rate.readFrom(_is); + return _is; +} + diff --git a/eo/src/utils/selectors.h b/eo/src/utils/selectors.h index 754d69541..fe2b39bd3 100644 --- a/eo/src/utils/selectors.h +++ b/eo/src/utils/selectors.h @@ -41,7 +41,7 @@ #include #include "eoRNG.h" - +#include /** \defgroup selectors */ diff --git a/eo/test/t-eoGA.cpp b/eo/test/t-eoGA.cpp index f501c7568..bba6d5cd8 100644 --- a/eo/test/t-eoGA.cpp +++ b/eo/test/t-eoGA.cpp @@ -11,32 +11,59 @@ int main(int argc, char* argv[]) try { - typedef eoBit EoType; + typedef eoBit EOT; - eoParser parser(argc, argv); + eoParser parser(argc, argv); // for user-parameter reading - eoState state; // keeps all things allocated, including eoEasyEA and eoPop! + eoState state; // keeps all things allocated - eoEvalFuncPtr eval( binary_value ); - eoGenContinue term(20); - eoCheckPoint checkpoint(term); + ///// FIRST, problem or representation dependent stuff + ////////////////////////////////////////////////////// - eoAlgo& ga = make_ga(parser, eval, checkpoint, state); + // The evaluation fn - encapsulated into an eval counter for output + eoEvalFuncPtr mainEval( binary_value ); + eoEvalFuncCounter eval(mainEval); - eoPop& pop = init_ga(parser, state, double()); + // the genotype - through a genotype initializer + eoInit& init = make_genotype(parser, state, double()); - if (parser.userNeedsHelp()) - { - parser.printHelp(cout); - return 0; - } + // Build the variation operator (any seq/prop construct) + eoGenOp& op = make_op(parser, state, init); + //// Now the representation-independent things + ////////////////////////////////////////////// + + // initialize the population - and evaluate + // yes, this is representation indepedent once you have an eoInit + eoPop& pop = make_pop(parser, state, init); apply(eval, pop); - run_ga(ga, pop); // run the ga + // stopping criteria + eoContinue & term = make_continue(parser, state, eval); + // output + eoCheckPoint & checkpoint = make_checkpoint(parser, state, eval, term); + // algorithm (need the operator!) + eoAlgo& ga = make_algo_scalar(parser, state, eval, checkpoint, op); + + ///// End of construction of the algorith + ///////////////////////////////////////// + // to be called AFTER all parameters have been read!!! + make_help(parser); + + //// GO + /////// + cout << "Initial Population\n"; + pop.sortedPrintOn(cout); + cout << endl; + + run_ea(ga, pop); // run the ga + + cout << "Final Population\n"; + pop.sortedPrintOn(cout); + cout << endl; } catch(exception& e) { cout << e.what() << endl; } -} \ No newline at end of file +} diff --git a/eo/test/t-eoRandom.cpp b/eo/test/t-eoRandom.cpp index c21b9cdc1..1091ddc3e 100644 --- a/eo/test/t-eoRandom.cpp +++ b/eo/test/t-eoRandom.cpp @@ -24,7 +24,7 @@ */ /** -CVS Info: $Date: 2001-03-14 10:14:27 $ $Author: maartenkeijzer $ $Revision: 1.11 $ +CVS Info: $Date: 2001-04-24 04:52:04 $ $Author: evomarc $ $Revision: 1.12 $ */ //----------------------------------------------------------------------------- @@ -37,7 +37,7 @@ CVS Info: $Date: 2001-03-14 10:14:27 $ $Author: maartenkeijzer $ $Revision: 1.1 //----------------------------------------------------------------------------- -main() { +int main() { eoUniformGenerator u1(-2.5,3.5); eoUniformGenerator u2(0.003, 0.05 ); eoUniformGenerator u3( 10000U, 10000000U); diff --git a/eo/test/t-eoSelect.cpp b/eo/test/t-eoSelect.cpp index 687da2cdf..c2c458757 100644 --- a/eo/test/t-eoSelect.cpp +++ b/eo/test/t-eoSelect.cpp @@ -65,7 +65,8 @@ void testSelectMany(eoSelect & _select, string _name) // initialize parents for (unsigned i=0; i tournamentSizeParam = parser.createParam detSelect(oRate); -// testSelectMany(detSelect, "detSelect"); + // eoDetSelect detSelect(oRate); + // testSelectMany(detSelect, "detSelect"); // Roulette -// eoProportionalSelect propSelect; -// testSelectOne(propSelect, oRate, "propSelect"); + eoProportionalSelect propSelect; + testSelectOne(propSelect, oRate, "propSelect"); // Ranking -// eoRankingSelect rankSelect(rankingPressure); -// testSelectOne(rankSelect, oRate, "rankSelect"); + eoRankingSelect rankSelect(rankingPressure); + testSelectOne(rankSelect, oRate, "rankSelect"); // New ranking using the perf2Worth construct cout << "Avant appel a LinearRanking()" << endl; @@ -161,6 +162,8 @@ eoValueParam tournamentSizeParam = parser.createParam stochTourSelect(tRate); testSelectOne(stochTourSelect, oRate, "stochTourSelect"); + exit(1); + // Fitness scaling // eoFitnessScalingSelect fitScaleSelect(rankingPressure); // testSelectOne(fitScaleSelect, oRate, "fitScaleSelect"); diff --git a/eo/test/t-eoStateAndParser.cpp b/eo/test/t-eoStateAndParser.cpp index 420da2343..c29338ddc 100644 --- a/eo/test/t-eoStateAndParser.cpp +++ b/eo/test/t-eoStateAndParser.cpp @@ -43,6 +43,12 @@ int the_main(int argc, char **argv) eoValueParam rate(0.01, "mutationRatePerBit", "Initial value for mutation rate per bit"); eoValueParam factor(0.99, "mutationFactor", "Decrease factor for mutation rate"); eoValueParam seed(time(0), "seed", "Random number seed"); + // test if user entered or if default value used + if (parser.isItThere(seed)) + cout << "YES\n"; + else + cout << "NO\n"; + eoValueParam load_name("", "Load","Load",'L'); eoValueParam save_name("", "Save","Save",'S'); diff --git a/eo/test/t-eoVector.cpp b/eo/test/t-eoVector.cpp index 7d241ae6f..759414c40 100644 --- a/eo/test/t-eoVector.cpp +++ b/eo/test/t-eoVector.cpp @@ -42,14 +42,14 @@ typedef eoVector Chrom2; //----------------------------------------------------------------------------- -main() +int main() { const unsigned SIZE = 4; // check if the appropriate ctor gets called Chrom1 chrom(SIZE, 5); - for (int i = 0; i < chrom.size(); ++i) + for (unsigned i = 0; i < chrom.size(); ++i) { assert(chrom[i] == 5); }