diff --git a/eo/src/do/make_checkpoint.h b/eo/src/do/make_checkpoint.h index 93488ac8..1d2cc63e 100644 --- a/eo/src/do/make_checkpoint.h +++ b/eo/src/do/make_checkpoint.h @@ -1,291 +1,292 @@ -// -*- 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 - -// at the moment, in utils/make_help.cpp -// this should become some eoUtils.cpp with corresponding eoUtils.h -bool testDirRes(std::string _dirName, bool _erase); -/////////////////// The checkpoint and other I/O ////////////// - - -template -eoCheckPoint& do_make_checkpoint(eoParser& _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"); - eoValueParam& useTimeParam = _parser.createParam(true, "useTime", "Display time (s) every generation", '\0', "Output"); - - // if we want the time, we need an eoTimeCounter - eoTimeCounter * tCounter = NULL; - - // Create anyway a generation-counter - // Recent change (03/2002): it is now an eoIncrementorParam, both - // a parameter AND updater so you can store it into the eoState - eoIncrementorParam *generationCounter = new eoIncrementorParam("Gen."); - // store it in the state - _state.storeFunctor(generationCounter); - // And add it to the checkpoint, - checkpoint->add(*generationCounter); - - // dir for DISK output - eoValueParam& dirNameParam = _parser.createParam(std::string("Res"), "resDir", "Directory to store DISK outputs", '\0', "Output - Disk"); - // shoudl we empty it if exists - eoValueParam& eraseParam = _parser.createParam(true, "eraseDir", "erase files in dirName if any", '\0', "Output - Disk"); - bool dirOK = false; // not tested yet - - ///////////////////////////////////////// - // 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 std::pair - * eoSortedPopStat : whole population - type std::string (!!) - * eoScalarFitnessStat: the fitnesses - type std::vector - */ - - // 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 - Graphical"); - eoValueParam& fileBestParam = _parser.createParam(false, "fileBestStat", "Output bes/avg/std to file", '\0', "Output - Disk"); - - eoBestFitnessStat *bestStat = NULL; - if ( printBestParam.value() || plotBestParam.value() || fileBestParam.value() ) - // 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; - // store it - _state.storeFunctor(popStat); - // add it to the checkpoint - checkpoint->add(*popStat); - } - - - // do we wnat some histogram of fitnesses snpashots? - eoValueParam plotHistogramParam = _parser.createParam(false, "plotHisto", "Plot histogram of fitnesses", '\0', "Output - Graphical"); - - /////////////// - // The monitors - /////////////// - // do we want an eoStdoutMonitor? - bool needStdoutMonitor = printBestParam.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 (useTimeParam.value()) // we want time - { - tCounter = new eoTimeCounter; - _state.storeFunctor(tCounter); - checkpoint->add(*tCounter); - monitor->add(*tCounter); - } - if (printBestParam.value()) - { - monitor->add(*bestStat); - monitor->add(*secondStat); - } - if ( printPopParam.value()) - monitor->add(*popStat); - } - - // first handle the dir test - if we need at least one file - if ( ( fileBestParam.value() || plotBestParam.value() || - plotHistogramParam.value() ) - && !dirOK ) // just in case we add something before - dirOK = testDirRes(dirNameParam.value(), eraseParam.value()); // TRUE - - if (fileBestParam.value()) // A file monitor for best & secondMoment - { -#ifdef _MSVC - std::string stmp = dirNameParam.value() + "\best.xg"; -#else - std::string stmp = dirNameParam.value() + "/best.xg"; -#endif - eoFileMonitor *fileMonitor = new eoFileMonitor(stmp); - // save and give to checkpoint - _state.storeFunctor(fileMonitor); - checkpoint->add(*fileMonitor); - // and feed with some statistics - fileMonitor->add(*generationCounter); - fileMonitor->add(_eval); - if (tCounter) // we want the time as well - { - // std::cout << "On met timecounter\n"; - fileMonitor->add(*tCounter); - } - fileMonitor->add(*bestStat); - fileMonitor->add(*secondStat); - } - - if (plotBestParam.value()) // an eoGnuplot1DMonitor for best & average - { - std::string stmp = dirNameParam.value() + "/gnu_best.xg"; - eoGnuplot1DMonitor *gnuMonitor = new eoGnuplot1DMonitor(stmp,minimizing_fitness()); - // save and give to checkpoint - _state.storeFunctor(gnuMonitor); - checkpoint->add(*gnuMonitor); - // and feed with some statistics - if (useEvalParam.value()) // do we want eval as X coordinate - gnuMonitor->add(_eval); - else if (tCounter) // or time? - gnuMonitor->add(*tCounter); - else // default: generation - gnuMonitor->add(*generationCounter); - gnuMonitor->add(*bestStat); - gnuMonitor->add(*averageStat); - } - - // historgram? - 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(dirNameParam.value()); - _state.storeFunctor(fitSnapshot); - // add any stat that is a std::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)) - { - // first make sure dirName is OK - if (! dirOK ) - dirOK = testDirRes(dirNameParam.value(), eraseParam.value()); // TRUE - - unsigned freq = (saveFrequencyParam.value()>0 ? saveFrequencyParam.value() : UINT_MAX ); -#ifdef _MSVC - std::string stmp = dirNameParam.value() + "\generations"; -#else - std::string stmp = dirNameParam.value() + "/generations"; -#endif - eoCountedStateSaver *stateSaver1 = new eoCountedStateSaver(freq, _state, stmp); - _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) - { - // first make sure dirName is OK - if (! dirOK ) - dirOK = testDirRes(dirNameParam.value(), eraseParam.value()); // TRUE - -#ifdef _MSVC - std::string stmp = dirNameParam.value() + "\time"; -#else - std::string stmp = dirNameParam.value() + "/time"; -#endif - eoTimedStateSaver *stateSaver2 = new eoTimedStateSaver(saveTimeIntervalParam.value(), _state, stmp); - _state.storeFunctor(stateSaver2); - checkpoint->add(*stateSaver2); - } - - // and that's it for the (control and) output - return *checkpoint; -} - -#endif +// -*- 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 + +// at the moment, in utils/make_help.cpp +// this should become some eoUtils.cpp with corresponding eoUtils.h +bool testDirRes(std::string _dirName, bool _erase); +/////////////////// The checkpoint and other I/O ////////////// + + +template +eoCheckPoint& do_make_checkpoint(eoParser& _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"); + eoValueParam& useTimeParam = _parser.createParam(true, "useTime", "Display time (s) every generation", '\0', "Output"); + + // if we want the time, we need an eoTimeCounter + eoTimeCounter * tCounter = NULL; + + // Create anyway a generation-counter + // Recent change (03/2002): it is now an eoIncrementorParam, both + // a parameter AND updater so you can store it into the eoState + eoIncrementorParam *generationCounter = new eoIncrementorParam("Gen."); + // store it in the state + _state.storeFunctor(generationCounter); + // And add it to the checkpoint, + checkpoint->add(*generationCounter); + + // dir for DISK output + eoValueParam& dirNameParam = _parser.createParam(std::string("Res"), "resDir", "Directory to store DISK outputs", '\0', "Output - Disk"); + // shoudl we empty it if exists + eoValueParam& eraseParam = _parser.createParam(true, "eraseDir", "erase files in dirName if any", '\0', "Output - Disk"); + bool dirOK = false; // not tested yet + + ///////////////////////////////////////// + // 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 std::pair + * eoSortedPopStat : whole population - type std::string (!!) + * eoScalarFitnessStat: the fitnesses - type std::vector + */ + + // 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 - Graphical"); + eoValueParam& fileBestParam = _parser.createParam(false, "fileBestStat", "Output bes/avg/std to file", '\0', "Output - Disk"); + + eoBestFitnessStat *bestStat = NULL; + if ( printBestParam.value() || plotBestParam.value() || fileBestParam.value() ) + // 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; + // store it + _state.storeFunctor(popStat); + // add it to the checkpoint + checkpoint->add(*popStat); + } + + + // do we wnat some histogram of fitnesses snpashots? + eoValueParam plotHistogramParam = _parser.createParam(false, "plotHisto", "Plot histogram of fitnesses", '\0', "Output - Graphical"); + + /////////////// + // The monitors + /////////////// + // do we want an eoStdoutMonitor? + bool needStdoutMonitor = printBestParam.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 (useTimeParam.value()) // we want time + { + tCounter = new eoTimeCounter; + _state.storeFunctor(tCounter); + checkpoint->add(*tCounter); + monitor->add(*tCounter); + } + if (printBestParam.value()) + { + monitor->add(*bestStat); + monitor->add(*secondStat); + } + if ( printPopParam.value()) + monitor->add(*popStat); + } + + // first handle the dir test - if we need at least one file + if ( ( fileBestParam.value() || plotBestParam.value() || + plotHistogramParam.value() ) + && !dirOK ) // just in case we add something before + dirOK = testDirRes(dirNameParam.value(), eraseParam.value()); // TRUE + + if (fileBestParam.value()) // A file monitor for best & secondMoment + { +#ifdef _MSVC + std::string stmp = dirNameParam.value() + "\best.xg"; +#else + std::string stmp = dirNameParam.value() + "/best.xg"; +#endif + eoFileMonitor *fileMonitor = new eoFileMonitor(stmp); + // save and give to checkpoint + _state.storeFunctor(fileMonitor); + checkpoint->add(*fileMonitor); + // and feed with some statistics + fileMonitor->add(*generationCounter); + fileMonitor->add(_eval); + if (tCounter) // we want the time as well + { + // std::cout << "On met timecounter\n"; + fileMonitor->add(*tCounter); + } + fileMonitor->add(*bestStat); + fileMonitor->add(*secondStat); + } + +#if !defined(NO_GNUPLOT) + if (plotBestParam.value()) // an eoGnuplot1DMonitor for best & average + { + std::string stmp = dirNameParam.value() + "/gnu_best.xg"; + eoGnuplot1DMonitor *gnuMonitor = new eoGnuplot1DMonitor(stmp,minimizing_fitness()); + // save and give to checkpoint + _state.storeFunctor(gnuMonitor); + checkpoint->add(*gnuMonitor); + // and feed with some statistics + if (useEvalParam.value()) // do we want eval as X coordinate + gnuMonitor->add(_eval); + else if (tCounter) // or time? + gnuMonitor->add(*tCounter); + else // default: generation + gnuMonitor->add(*generationCounter); + gnuMonitor->add(*bestStat); + gnuMonitor->add(*averageStat); + } + + // historgram? + 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(dirNameParam.value()); + _state.storeFunctor(fitSnapshot); + // add any stat that is a std::vector to it + fitSnapshot->add(*fitStat); + // and of course add it to the checkpoint + checkpoint->add(*fitSnapshot); + } +#endif + ////////////////////////////////// + // 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)) + { + // first make sure dirName is OK + if (! dirOK ) + dirOK = testDirRes(dirNameParam.value(), eraseParam.value()); // TRUE + + unsigned freq = (saveFrequencyParam.value()>0 ? saveFrequencyParam.value() : UINT_MAX ); +#ifdef _MSVC + std::string stmp = dirNameParam.value() + "\generations"; +#else + std::string stmp = dirNameParam.value() + "/generations"; +#endif + eoCountedStateSaver *stateSaver1 = new eoCountedStateSaver(freq, _state, stmp); + _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) + { + // first make sure dirName is OK + if (! dirOK ) + dirOK = testDirRes(dirNameParam.value(), eraseParam.value()); // TRUE + +#ifdef _MSVC + std::string stmp = dirNameParam.value() + "\time"; +#else + std::string stmp = dirNameParam.value() + "/time"; +#endif + eoTimedStateSaver *stateSaver2 = new eoTimedStateSaver(saveTimeIntervalParam.value(), _state, stmp); + _state.storeFunctor(stateSaver2); + checkpoint->add(*stateSaver2); + } + + // and that's it for the (control and) output + return *checkpoint; +} + +#endif diff --git a/eo/src/eoScalarFitness.h b/eo/src/eoScalarFitness.h index 8402e1e9..f31a5783 100644 --- a/eo/src/eoScalarFitness.h +++ b/eo/src/eoScalarFitness.h @@ -1,99 +1,104 @@ -/* -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- - - ----------------------------------------------------------------------------- - eoScalarFitness.h - - (c) Maarten Keijzer (mkeijzer@mad.scientist.com) and GeNeura Team, 1999, 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 - */ - - -#ifndef eoScalarFitness_h -#define eoScalarFitness_h - -#include -#include - -/** - * eoScalarFitness >: - * Wraps a scalar fitness values such as a double or int, with the option of - * maximizing (using less) or minimizing (using greater) - - * It overrides operator<() to use the Compare template argument - * - * Suitable constructors and assignments and casts are defined to work - * with this quantity as if it were a ScalarType. -*/ -template -class eoScalarFitness -{ - public : - - eoScalarFitness() : value() {} - eoScalarFitness(const eoScalarFitness& other) : value(other.value) {} - eoScalarFitness(const ScalarType& v) : value(v) {} - - eoScalarFitness& operator=(const eoScalarFitness& other) - { value = other.value; return *this; } - eoScalarFitness& operator=(const ScalarType& v) - { value = v; return *this; } - - operator ScalarType(void) const { return value; } - - /// Comparison, using less by default - bool operator<(const eoScalarFitness& other) const - { return Compare()(value, other.value); } - - // implementation of the other operators - bool operator>( const eoScalarFitness& y ) const { return y < *this; } - // implementation of the other operators - bool operator<=( const eoScalarFitness& y ) const { return !(*this > y); } - // implementation of the other operators - bool operator>=(const eoScalarFitness& y ) const { return !(*this < y); } - - - private : - ScalarType value; -}; - -/** -Typedefs for fitness comparison, Maximizing Fitness compares with less, -and minimizing fitness compares with greater. This because we want ordinary -fitness values (doubles) to be equivalent with Maximizing Fitness, and -comparing with less is the default behaviour. -*/ -typedef eoScalarFitness > eoMaximizingFitness; -typedef eoScalarFitness > eoMinimizingFitness; - -template -std::ostream& operator<<(std::ostream& os, const eoScalarFitness& f) -{ - os << (F) f; - return os; -} - -template -std::istream& operator>>(std::istream& is, eoScalarFitness& f) -{ - F value; - is >> value; - f = value; - return is; -} - -#endif +/* -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + + ----------------------------------------------------------------------------- + eoScalarFitness.h + + (c) Maarten Keijzer (mkeijzer@mad.scientist.com) and GeNeura Team, 1999, 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 + */ + + +#ifndef eoScalarFitness_h +#define eoScalarFitness_h + +#include +#include + +/** + * eoScalarFitness >: + * Wraps a scalar fitness values such as a double or int, with the option of + * maximizing (using less) or minimizing (using greater) + + * It overrides operator<() to use the Compare template argument + * + * Suitable constructors and assignments and casts are defined to work + * with this quantity as if it were a ScalarType. +*/ +template +class eoScalarFitness +{ + public : + + eoScalarFitness() : value() {} + eoScalarFitness(const eoScalarFitness& other) : value(other.value) {} + eoScalarFitness(const ScalarType& v) : value(v) {} + + eoScalarFitness& operator=(const eoScalarFitness& other) + { value = other.value; return *this; } + eoScalarFitness& operator=(const ScalarType& v) + { value = v; return *this; } + + operator ScalarType(void) const { return value; } + + /// Comparison, using less by default + bool operator<(const eoScalarFitness& other) const + { return Compare()(value, other.value); } + + /// Comparison, using less by default + // needed for MSVC 8 (MSVC 2005) added by J.Eggermont 20-11-2006 + bool operator<(const ScalarType& other) const + { return Compare()(value, other); } + + // implementation of the other operators + bool operator>( const eoScalarFitness& y ) const { return y < *this; } + // implementation of the other operators + bool operator<=( const eoScalarFitness& y ) const { return !(*this > y); } + // implementation of the other operators + bool operator>=(const eoScalarFitness& y ) const { return !(*this < y); } + + + private : + ScalarType value; +}; + +/** +Typedefs for fitness comparison, Maximizing Fitness compares with less, +and minimizing fitness compares with greater. This because we want ordinary +fitness values (doubles) to be equivalent with Maximizing Fitness, and +comparing with less is the default behaviour. +*/ +typedef eoScalarFitness > eoMaximizingFitness; +typedef eoScalarFitness > eoMinimizingFitness; + +template +std::ostream& operator<<(std::ostream& os, const eoScalarFitness& f) +{ + os << (F) f; + return os; +} + +template +std::istream& operator>>(std::istream& is, eoScalarFitness& f) +{ + F value; + is >> value; + f = value; + return is; +} + +#endif diff --git a/eo/src/eoSelectOne.h b/eo/src/eoSelectOne.h index 34b0782f..20fced24 100644 --- a/eo/src/eoSelectOne.h +++ b/eo/src/eoSelectOne.h @@ -1,54 +1,54 @@ -/** -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- - - ----------------------------------------------------------------------------- - eoSelectOne.h - (c) Maarten Keijzer, 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 - */ -//----------------------------------------------------------------------------- - -#ifndef _eoSelectOne_h -#define _eoSelectOne_h - - -//----------------------------------------------------------------------------- -#include -#include -//----------------------------------------------------------------------------- - -/** eoSelectOne selects only one element from a whole population. - Most selection techniques are simply repeated applications - of eoSelectOne. - - @see eoSelectMany, eoSelectRandom, eoDetTournament, eoStochTournament, eoProportional -*/ -#ifdef _MSC_VER -template -#else -template -#endif -class eoSelectOne : public eoUF&, const EOT&> -{ - public : - /// virtual function to setup some population stats (for instance eoProportional can benefit greatly from this) - virtual void setup(const eoPop& _pop) - {} -}; - - -#endif +/** -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + + ----------------------------------------------------------------------------- + eoSelectOne.h + (c) Maarten Keijzer, 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 + */ +//----------------------------------------------------------------------------- + +#ifndef _eoSelectOne_h +#define _eoSelectOne_h + + +//----------------------------------------------------------------------------- +#include +#include +//----------------------------------------------------------------------------- + +/** eoSelectOne selects only one element from a whole population. + Most selection techniques are simply repeated applications + of eoSelectOne. + + @see eoSelectMany, eoSelectRandom, eoDetTournament, eoStochTournament, eoProportional +*/ +#if defined(_MSC_VER) && (_MSC_VER < 1300) +template +#else +template +#endif +class eoSelectOne : public eoUF&, const EOT&> +{ + public : + /// virtual function to setup some population stats (for instance eoProportional can benefit greatly from this) + virtual void setup(const eoPop& _pop) + {} +}; + + +#endif diff --git a/eo/src/utils/eoMOFitnessStat.h b/eo/src/utils/eoMOFitnessStat.h index bb95acbe..64102139 100644 --- a/eo/src/utils/eoMOFitnessStat.h +++ b/eo/src/utils/eoMOFitnessStat.h @@ -1,91 +1,91 @@ -// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- - -//----------------------------------------------------------------------------- -// eoFitnessStat.h -// (c) Marc Schoenauer, Maarten Keijzer and GeNeura Team, 2000, 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 _eoFitnessStat_h -#define _eoFitnessStat_h - -#include - -/** - The fitnesses of a whole population, as a vector -*/ -template -class eoFitnessStat : public eoSortedStat > -{ -public : - - using eoSortedStat >::value; - - eoFitnessStat(std::string _description = "AllFitnesses") : - eoSortedStat >(std::vector(0), _description) {} - - virtual void operator()(const std::vector& _popPters) - { - value().resize(_popPters.size()); - for (unsigned i=0; i<_popPters.size(); i++) - value()[i] = _popPters[i]->fitness(); - } -}; - - -/** For multi-objective fitness, we need to translate a stat > - into a vector, so each objective gets a seperate stat -*/ -#ifdef _MSC_VER -// The follownig is needed to avoid some bug in Visual Studio 6.0 -typedef double PartFitDefault; -template -class eoMOFitnessStat : public eoSortedStat > -#else -template -class eoMOFitnessStat : public eoSortedStat > -#endif - -{ -public: - - using eoSortedStat >::value; - - /** Ctor: say what component you want - */ - eoMOFitnessStat(unsigned _objective, std::string _description = "MO-Fitness") : - eoSortedStat >(std::vector(0), _description), - objective(_objective) {} - - virtual void operator()(const std::vector& _popPters) - { - value().resize(_popPters.size()); - - for (unsigned i=0; i<_popPters.size(); i++) - { - value()[i] = _popPters[i]->fitness()[objective]; - } - } -private: - unsigned int objective; // The objective we're storing - -}; -#endif +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// eoFitnessStat.h +// (c) Marc Schoenauer, Maarten Keijzer and GeNeura Team, 2000, 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 _eoFitnessStat_h +#define _eoFitnessStat_h + +#include + +/** + The fitnesses of a whole population, as a vector +*/ +template +class eoFitnessStat : public eoSortedStat > +{ +public : + + using eoSortedStat >::value; + + eoFitnessStat(std::string _description = "AllFitnesses") : + eoSortedStat >(std::vector(0), _description) {} + + virtual void operator()(const std::vector& _popPters) + { + value().resize(_popPters.size()); + for (unsigned i=0; i<_popPters.size(); i++) + value()[i] = _popPters[i]->fitness(); + } +}; + + +/** For multi-objective fitness, we need to translate a stat > + into a vector, so each objective gets a seperate stat +*/ +#ifdef _MSC_VER +// The follownig is needed to avoid some bug in Visual Studio 6.0 +typedef double PartFitDefault; +template +class eoMOFitnessStat : public eoSortedStat > +#else +template +class eoMOFitnessStat : public eoSortedStat > +#endif + +{ +public: + + using eoSortedStat >::value; + + /** Ctor: say what component you want + */ + eoMOFitnessStat(unsigned _objective, std::string _description = "MO-Fitness") : + eoSortedStat >(std::vector(0), _description), + objective(_objective) {} + + virtual void operator()(const std::vector& _popPters) + { + value().resize(_popPters.size()); + + for (unsigned i=0; i<_popPters.size(); i++) + { + value()[i] = _popPters[i]->fitness()[objective]; + } + } +private: + unsigned int objective; // The objective we're storing + +}; +#endif diff --git a/eo/src/utils/eoRNG.h b/eo/src/utils/eoRNG.h index ae5797c1..003b3fe1 100644 --- a/eo/src/utils/eoRNG.h +++ b/eo/src/utils/eoRNG.h @@ -32,11 +32,19 @@ Contact: todos@geneura.ugr.es, http://geneura.ugr.es // // The C99-standard defines uint32_t to be declared in stdint.h, but some // systmes don't have that and implement it in inttypes.h. + +// first if check added for MSVC by Jeroen Eggermont 20-11-2006, needed for MSVC 2003 (and 2005) +# if (defined _MSC_VER) +typedef unsigned long uint32_t; +#include +#else #if (! defined __sun) #include #else #include #endif +#endif + #include #include "eoPersistent.h" diff --git a/eo/src/utils/eoStat.h b/eo/src/utils/eoStat.h index 87706386..06afa3fc 100644 --- a/eo/src/utils/eoStat.h +++ b/eo/src/utils/eoStat.h @@ -102,7 +102,7 @@ public : ( For eoScalarFitnessAssembled user eoAssembledFitnessStat classes.) */ -#ifdef _MSC_VER +#if defined(_MSC_VER) && (_MSC_VER < 1300) template class eoAverageStat : public eoStat #else template class eoAverageStat : public eoStat @@ -203,7 +203,7 @@ public : /** The n_th element fitness in the population (see eoBestFitnessStat) */ -#ifdef _MSC_VER +#if defined(_MSC_VER) && (_MSC_VER < 1300) template class eoNthElementFitnessStat : public eoSortedStat #else @@ -308,7 +308,7 @@ public : ( For eoScalarFitnessAssembled look at eoAssembledFitnessStat ) */ -#ifdef _MSC_VER +#if defined(_MSC_VER) && (_MSC_VER < 1300) template class eoBestFitnessStat : public eoStat #else diff --git a/eo/src/utils/selectors.h b/eo/src/utils/selectors.h index 86f2a0a6..43d28a0f 100644 --- a/eo/src/utils/selectors.h +++ b/eo/src/utils/selectors.h @@ -1,338 +1,338 @@ -/* -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- - - ----------------------------------------------------------------------------- - selectors.h - A bunch of useful selector functions. They generally have three forms: - - template - It select(It begin, It end, params, eoRng& gen = rng); - - template - const EOT& select(const eoPop& pop, params, eoRng& gen = rng); - - template - EOT& select(eoPop& pop, params, eoRng& gen = rng); - - where select is one of: roulette_wheel, deterministic_tournament - and stochastic_tournament (at the moment). - - (c) Maarten Keijzer (mak@dhi.dk) and GeNeura Team, 1999, 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 - */ - -#ifndef SELECT__H -#define SELECT__H - -#include - -#include "eoRNG.h" -#include -/** -\defgroup selectors -*/ - -template -bool minimizing_fitness() -{ - EOT eo1; // Assuming people don't do anything fancy in the default constructor! - EOT eo2; - - /* Dear user, when the two line below do not compile you are most - likely not working with scalar fitness values. In that case we're sorry - but you cannot use lottery or roulette_wheel selection... - */ - -#ifdef _MSC_VER - eo1.fitness( EOT::Fitness(0.0) ); - eo2.fitness( EOT::Fitness(1.0) ); -#else - eo1.fitness( typename EOT::Fitness(0.0) ); // tried to cast it to an EOT::Fitness, but for some reason GNU barfs on this - eo2.fitness( typename EOT::Fitness(1.0) ); -#endif - - return eo2 < eo1; // check whether we have a minimizing fitness -} - -inline double scale_fitness(const std::pair& _minmax, double _value) -{ - if (_minmax.first == _minmax.second) - { - return 0.0; // no differences in fitness, population converged! - } - // else - - return (_value - _minmax.first) / (_minmax.second - _minmax.first); -} - -template -double sum_fitness(It begin, It end) -{ - double sum = 0.0; - - for (; begin != end; ++begin) - { - double v = static_cast(begin->fitness()); - if (v < 0.0) - throw std::logic_error("sum_fitness: negative fitness value encountered"); - sum += v; - } - - return sum; -} - -template -double sum_fitness(const eoPop& _pop) -{ - return sum_fitness(_pop.begin(), _pop.end()); -} - -template -double sum_fitness(const eoPop& _pop, std::pair& _minmax) -{ - double rawTotal, scaledTotal; - - typename eoPop::const_iterator it = _pop.begin(); - - _minmax.first = it->fitness(); - _minmax.second = it++->fitness(); - - for(; it != _pop.end(); ++it) - { - double v = static_cast(it->fitness()); - - _minmax.first = std::min(_minmax.first, v); - _minmax.second = std::max(_minmax.second, v); - - rawTotal += v; - } - - if (minimizing_fitness()) - { - std::swap(_minmax.first, _minmax.second); - } - - scaledTotal = 0.0; - - // unfortunately a second loop is neccessary to scale the fitness - for (it = _pop.begin(); it != _pop.end(); ++it) - { - double v = scale_fitness(_minmax, static_cast(it->fitness())); - - scaledTotal += v; - } - - return scaledTotal; -} - -template -It roulette_wheel(It _begin, It _end, double total, eoRng& _gen = rng) -{ - - float roulette = _gen.uniform(total); - - if (roulette == 0.0) // covers the case where total==0.0 - return _begin + _gen.random(_end - _begin); // uniform choice - - It i = _begin; - - while (roulette > 0.0) - { - roulette -= static_cast(*(i++)); - } - - return --i; -} - -template -const EOT& roulette_wheel(const eoPop& _pop, double total, eoRng& _gen = rng) -{ - float roulette = _gen.uniform(total); - - if (roulette == 0.0) // covers the case where total==0.0 - return _pop[_gen.random(_pop.size())]; // uniform choice - - typename eoPop::const_iterator i = _pop.begin(); - - while (roulette > 0.0) - { - roulette -= static_cast((i++)->fitness()); - } - - return *--i; -} - -template -EOT& roulette_wheel(eoPop& _pop, double total, eoRng& _gen = rng) -{ - float roulette = _gen.uniform(total); - - if (roulette == 0.0) // covers the case where total==0.0 - return _pop[_gen.random(_pop.size())]; // uniform choice - - typename eoPop::iterator i = _pop.begin(); - - while (roulette > 0.0) - { - roulette -= static_cast((i++)->fitness()); - } - - return *--i; -} - -template -It deterministic_tournament(It _begin, It _end, unsigned _t_size, eoRng& _gen = rng) -{ - It best = _begin + _gen.random(_end - _begin); - - for (unsigned i = 0; i < _t_size - 1; ++i) - { - It competitor = _begin + _gen.random(_end - _begin); - - if (*best < *competitor) - { - best = competitor; - } - } - - return best; -} - -template -const EOT& deterministic_tournament(const eoPop& _pop, unsigned _t_size, eoRng& _gen = rng) -{ - return *deterministic_tournament(_pop.begin(), _pop.end(), _t_size, _gen); -} - -template -EOT& deterministic_tournament(eoPop& _pop, unsigned _t_size, eoRng& _gen = rng) -{ - return *deterministic_tournament(_pop.begin(), _pop.end(), _t_size, _gen); -} - -template -It inverse_deterministic_tournament(It _begin, It _end, unsigned _t_size, eoRng& _gen = rng) -{ - It worst = _begin + _gen.random(_end - _begin); - - for (unsigned i = 1; i < _t_size; ++i) - { - It competitor = _begin + _gen.random(_end - _begin); - - if (competitor == worst) - { - --i; - continue; // try again - } - - if (*competitor < *worst) - { - worst = competitor; - } - } - - return worst; -} - -template -const EOT& inverse_deterministic_tournament(const eoPop& _pop, unsigned _t_size, eoRng& _gen = rng) -{ - return *inverse_deterministic_tournament(_pop.begin(), _pop.end(), _t_size, _gen); -} - -template -EOT& inverse_deterministic_tournament(eoPop& _pop, unsigned _t_size, eoRng& _gen = rng) -{ - return *inverse_deterministic_tournament(_pop.begin(), _pop.end(), _t_size, _gen); -} - -template -It stochastic_tournament(It _begin, It _end, double _t_rate, eoRng& _gen = rng) -{ - It i1 = _begin + _gen.random(_end - _begin); - It i2 = _begin + _gen.random(_end - _begin); - - bool return_better = _gen.flip(_t_rate); - - if (*i1 < *i2) - { - if (return_better) return i2; - // else - - return i1; - } - else - { - if (return_better) return i1; - // else - } - // else - - return i2; -} - -template -const EOT& stochastic_tournament(const eoPop& _pop, double _t_rate, eoRng& _gen = rng) -{ - return *stochastic_tournament(_pop.begin(), _pop.end(), _t_rate, _gen); -} - -template -EOT& stochastic_tournament(eoPop& _pop, double _t_rate, eoRng& _gen = rng) -{ - return *stochastic_tournament(_pop.begin(), _pop.end(), _t_rate, _gen); -} - -template -It inverse_stochastic_tournament(It _begin, It _end, double _t_rate, eoRng& _gen = rng) -{ - It i1 = _begin + _gen.random(_end - _begin); - It i2 = _begin + _gen.random(_end - _begin); - - bool return_worse = _gen.flip(_t_rate); - - if (*i1 < *i2) - { - if (return_worse) return i1; - // else - - return i2; - } - else - { - if (return_worse) return i2; - // else - } - // else - - return i1; -} - -template -const EOT& inverse_stochastic_tournament(const eoPop& _pop, double _t_rate, eoRng& _gen = rng) -{ - return *inverse_stochastic_tournament(_pop.begin(), _pop.end(), _t_rate, _gen); -} - -template -EOT& inverse_stochastic_tournament(eoPop& _pop, double _t_rate, eoRng& _gen = rng) -{ - return *inverse_stochastic_tournament(_pop.begin(), _pop.end(), _t_rate, _gen); -} - - -#endif +/* -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + + ----------------------------------------------------------------------------- + selectors.h + A bunch of useful selector functions. They generally have three forms: + + template + It select(It begin, It end, params, eoRng& gen = rng); + + template + const EOT& select(const eoPop& pop, params, eoRng& gen = rng); + + template + EOT& select(eoPop& pop, params, eoRng& gen = rng); + + where select is one of: roulette_wheel, deterministic_tournament + and stochastic_tournament (at the moment). + + (c) Maarten Keijzer (mak@dhi.dk) and GeNeura Team, 1999, 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 + */ + +#ifndef SELECT__H +#define SELECT__H + +#include + +#include "eoRNG.h" +#include +/** +\defgroup selectors +*/ + +template +bool minimizing_fitness() +{ + EOT eo1; // Assuming people don't do anything fancy in the default constructor! + EOT eo2; + + /* Dear user, when the two line below do not compile you are most + likely not working with scalar fitness values. In that case we're sorry + but you cannot use lottery or roulette_wheel selection... + */ + +#ifdef _MSC_VER + eo1.fitness( EOT::Fitness(0.0) ); + eo2.fitness( EOT::Fitness(1.0) ); +#else + eo1.fitness( typename EOT::Fitness(0.0) ); // tried to cast it to an EOT::Fitness, but for some reason GNU barfs on this + eo2.fitness( typename EOT::Fitness(1.0) ); +#endif + + return eo2 < eo1; // check whether we have a minimizing fitness +} + +inline double scale_fitness(const std::pair& _minmax, double _value) +{ + if (_minmax.first == _minmax.second) + { + return 0.0; // no differences in fitness, population converged! + } + // else + + return (_value - _minmax.first) / (_minmax.second - _minmax.first); +} + +template +double sum_fitness(It begin, It end) +{ + double sum = 0.0; + + for (; begin != end; ++begin) + { + double v = static_cast(begin->fitness()); + if (v < 0.0) + throw std::logic_error("sum_fitness: negative fitness value encountered"); + sum += v; + } + + return sum; +} + +template +double sum_fitness(const eoPop& _pop) +{ + return sum_fitness(_pop.begin(), _pop.end()); +} + +template +double sum_fitness(const eoPop& _pop, std::pair& _minmax) +{ + double rawTotal, scaledTotal; + + typename eoPop::const_iterator it = _pop.begin(); + + _minmax.first = it->fitness(); + _minmax.second = it++->fitness(); + + for(; it != _pop.end(); ++it) + { + double v = static_cast(it->fitness()); + + _minmax.first = std::min(_minmax.first, v); + _minmax.second = std::max(_minmax.second, v); + + rawTotal += v; + } + + if (minimizing_fitness()) + { + std::swap(_minmax.first, _minmax.second); + } + + scaledTotal = 0.0; + + // unfortunately a second loop is neccessary to scale the fitness + for (it = _pop.begin(); it != _pop.end(); ++it) + { + double v = scale_fitness(_minmax, static_cast(it->fitness())); + + scaledTotal += v; + } + + return scaledTotal; +} + +template +It roulette_wheel(It _begin, It _end, double total, eoRng& _gen = rng) +{ + + float roulette = _gen.uniform(total); + + if (roulette == 0.0) // covers the case where total==0.0 + return _begin + _gen.random(_end - _begin); // uniform choice + + It i = _begin; + + while (roulette > 0.0) + { + roulette -= static_cast(*(i++)); + } + + return --i; +} + +template +const EOT& roulette_wheel(const eoPop& _pop, double total, eoRng& _gen = rng) +{ + float roulette = _gen.uniform(total); + + if (roulette == 0.0) // covers the case where total==0.0 + return _pop[_gen.random(_pop.size())]; // uniform choice + + typename eoPop::const_iterator i = _pop.begin(); + + while (roulette > 0.0) + { + roulette -= static_cast((i++)->fitness()); + } + + return *--i; +} + +template +EOT& roulette_wheel(eoPop& _pop, double total, eoRng& _gen = rng) +{ + float roulette = _gen.uniform(total); + + if (roulette == 0.0) // covers the case where total==0.0 + return _pop[_gen.random(_pop.size())]; // uniform choice + + typename eoPop::iterator i = _pop.begin(); + + while (roulette > 0.0) + { + roulette -= static_cast((i++)->fitness()); + } + + return *--i; +} + +template +It deterministic_tournament(It _begin, It _end, unsigned _t_size, eoRng& _gen = rng) +{ + It best = _begin + _gen.random(_end - _begin); + + for (unsigned i = 0; i < _t_size - 1; ++i) + { + It competitor = _begin + _gen.random(_end - _begin); + + if (*best < *competitor) + { + best = competitor; + } + } + + return best; +} + +template +const EOT& deterministic_tournament(const eoPop& _pop, unsigned _t_size, eoRng& _gen = rng) +{ + return *deterministic_tournament(_pop.begin(), _pop.end(), _t_size, _gen); +} + +template +EOT& deterministic_tournament(eoPop& _pop, unsigned _t_size, eoRng& _gen = rng) +{ + return *deterministic_tournament(_pop.begin(), _pop.end(), _t_size, _gen); +} + +template +It inverse_deterministic_tournament(It _begin, It _end, unsigned _t_size, eoRng& _gen = rng) +{ + It worst = _begin + _gen.random(_end - _begin); + + for (unsigned i = 1; i < _t_size; ++i) + { + It competitor = _begin + _gen.random(_end - _begin); + + if (competitor == worst) + { + --i; + continue; // try again + } + + if (*competitor < *worst) + { + worst = competitor; + } + } + + return worst; +} + +template +const EOT& inverse_deterministic_tournament(const eoPop& _pop, unsigned _t_size, eoRng& _gen = rng) +{ + return *inverse_deterministic_tournament(_pop.begin(), _pop.end(), _t_size, _gen); +} + +template +EOT& inverse_deterministic_tournament(eoPop& _pop, unsigned _t_size, eoRng& _gen = rng) +{ + return *inverse_deterministic_tournament(_pop.begin(), _pop.end(), _t_size, _gen); +} + +template +It stochastic_tournament(It _begin, It _end, double _t_rate, eoRng& _gen = rng) +{ + It i1 = _begin + _gen.random(_end - _begin); + It i2 = _begin + _gen.random(_end - _begin); + + bool return_better = _gen.flip(_t_rate); + + if (*i1 < *i2) + { + if (return_better) return i2; + // else + + return i1; + } + else + { + if (return_better) return i1; + // else + } + // else + + return i2; +} + +template +const EOT& stochastic_tournament(const eoPop& _pop, double _t_rate, eoRng& _gen = rng) +{ + return *stochastic_tournament(_pop.begin(), _pop.end(), _t_rate, _gen); +} + +template +EOT& stochastic_tournament(eoPop& _pop, double _t_rate, eoRng& _gen = rng) +{ + return *stochastic_tournament(_pop.begin(), _pop.end(), _t_rate, _gen); +} + +template +It inverse_stochastic_tournament(It _begin, It _end, double _t_rate, eoRng& _gen = rng) +{ + It i1 = _begin + _gen.random(_end - _begin); + It i2 = _begin + _gen.random(_end - _begin); + + bool return_worse = _gen.flip(_t_rate); + + if (*i1 < *i2) + { + if (return_worse) return i1; + // else + + return i2; + } + else + { + if (return_worse) return i2; + // else + } + // else + + return i1; +} + +template +const EOT& inverse_stochastic_tournament(const eoPop& _pop, double _t_rate, eoRng& _gen = rng) +{ + return *inverse_stochastic_tournament(_pop.begin(), _pop.end(), _t_rate, _gen); +} + +template +EOT& inverse_stochastic_tournament(eoPop& _pop, double _t_rate, eoRng& _gen = rng) +{ + return *inverse_stochastic_tournament(_pop.begin(), _pop.end(), _t_rate, _gen); +} + + +#endif