A full working version of ES is now available in tutorial/Lesson4,
that makes full use of libes.a. The user guide is in Lesson4 of the tutorial - programmer's guide will come later. Plus many small changes here and there
This commit is contained in:
parent
eb25bf0ab5
commit
5508869d00
19 changed files with 653 additions and 189 deletions
|
|
@ -33,6 +33,9 @@
|
|||
#include <eoEvalFuncCounter.h>
|
||||
#include <utils/checkpointing>
|
||||
|
||||
// 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 //////////////
|
||||
|
||||
|
||||
|
|
@ -58,6 +61,12 @@ eoCheckPoint<EOT>& do_make_checkpoint(eoParameterLoader& _parser, eoState& _stat
|
|||
// and store it in the state
|
||||
_state.storeFunctor(increment);
|
||||
|
||||
// dir for DISK output
|
||||
eoValueParam<string>& dirNameParam = _parser.createParam(string("Res"), "resDir", "Directory to store DISK outputs", '\0', "Output - Disk");
|
||||
// shoudl we empty it if exists
|
||||
eoValueParam<bool>& eraseParam = _parser.createParam(false, "eraseDir", "erase files in dirName if any", '\0', "Output - Disk");
|
||||
bool dirOK = false; // not tested yet
|
||||
|
||||
/////////////////////////////////////////
|
||||
// now some statistics on the population:
|
||||
/////////////////////////////////////////
|
||||
|
|
@ -78,12 +87,8 @@ eoCheckPoint<EOT>& do_make_checkpoint(eoParameterLoader& _parser, eoState& _stat
|
|||
//---------------------------
|
||||
eoValueParam<bool>& printBestParam = _parser.createParam(true, "printBestStat", "Print Best/avg/stdev every gen.", '\0', "Output");
|
||||
eoValueParam<bool>& plotBestParam = _parser.createParam(false, "plotBestStat", "Plot Best/avg Stat", '\0', "Output - Graphical");
|
||||
|
||||
// dir for DISK output
|
||||
eoValueParam<string>& dirNameParam = _parser.createParam(string("Res"), "resDir", "Directory to store DISK outputs", '\0', "Output - Disk");
|
||||
eoValueParam<bool>& fileBestParam = _parser.createParam(false, "fileBestStat", "Output bes/avg/std to file", '\0', "Output - Disk");
|
||||
|
||||
|
||||
eoBestFitnessStat<EOT> *bestStat = NULL;
|
||||
if ( printBestParam.value() || plotBestParam.value() || fileBestParam.value() )
|
||||
// we need the bestStat for at least one of the 3 above
|
||||
|
|
@ -152,6 +157,9 @@ eoCheckPoint<EOT>& do_make_checkpoint(eoParameterLoader& _parser, eoState& _stat
|
|||
checkpoint->add(*fdcStat);
|
||||
}
|
||||
|
||||
// do we wnat some histogram of fitnesses snpashots?
|
||||
eoValueParam<bool> plotHistogramParam = _parser.createParam(false, "plotHisto", "Plot histogram of fitnesses", '\0', "Output - Graphical");
|
||||
|
||||
///////////////
|
||||
// The monitors
|
||||
///////////////
|
||||
|
|
@ -183,6 +191,12 @@ eoCheckPoint<EOT>& do_make_checkpoint(eoParameterLoader& _parser, eoState& _stat
|
|||
monitor->add(*popStat);
|
||||
}
|
||||
|
||||
// first handle the dir test - if we need at least one file
|
||||
if ( ( fileBestParam.value() || plotBestParam.value() ||
|
||||
plotFDCParam.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
|
||||
{
|
||||
string stmp = dirNameParam.value() + "/best.xg";
|
||||
|
|
@ -227,7 +241,7 @@ eoCheckPoint<EOT>& do_make_checkpoint(eoParameterLoader& _parser, eoState& _stat
|
|||
checkpoint->add(*fdcGnuplot);
|
||||
}
|
||||
|
||||
eoValueParam<bool> plotHistogramParam = _parser.createParam(false, "plotHisto", "Plot histogram of fitnesses", '\0', "Output - Graphical");
|
||||
// historgram?
|
||||
if (plotHistogramParam.value()) // want to see how the fitness is spread?
|
||||
{
|
||||
eoScalarFitnessStat<EOT> *fitStat = new eoScalarFitnessStat<EOT>;
|
||||
|
|
@ -252,6 +266,10 @@ eoCheckPoint<EOT>& do_make_checkpoint(eoParameterLoader& _parser, eoState& _stat
|
|||
|
||||
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 );
|
||||
string stmp = dirNameParam.value() + "/generations";
|
||||
eoCountedStateSaver *stateSaver1 = new eoCountedStateSaver(freq, _state, stmp);
|
||||
|
|
@ -263,6 +281,10 @@ eoCheckPoint<EOT>& do_make_checkpoint(eoParameterLoader& _parser, eoState& _stat
|
|||
eoValueParam<unsigned>& 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
|
||||
|
||||
string stmp = dirNameParam.value() + "/time";
|
||||
eoTimedStateSaver *stateSaver2 = new eoTimedStateSaver(saveTimeIntervalParam.value(), _state, stmp);
|
||||
_state.storeFunctor(stateSaver2);
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#ifndef _make_pop_h
|
||||
#define _make_pop_h
|
||||
|
||||
#include <sys/time.h> // for time(0) for random seeding
|
||||
#include <eoPop.h>
|
||||
#include <eoInit.h>
|
||||
#include <utils/eoRNG.h>
|
||||
|
|
@ -50,7 +51,7 @@ eoPop<EOT>& do_make_pop(eoParser & _parser, eoState& _state, eoInit<EOT> & _ini
|
|||
// random seed
|
||||
eoValueParam<uint32>& seedParam = _parser.createParam(uint32(0), "seed", "Random number seed", 'S');
|
||||
if (seedParam.value() == 0)
|
||||
seedParam.value() = random_seed();
|
||||
seedParam.value() = time(0);
|
||||
eoValueParam<unsigned>& popSize = _parser.createParam(unsigned(20), "popSize", "Population Size", 'P', "Evolution Engine");
|
||||
|
||||
// Either load or initialize
|
||||
|
|
|
|||
|
|
@ -90,10 +90,10 @@ class eoEsMutationInit
|
|||
virtual std::string section(void)
|
||||
{ return repSection; }
|
||||
|
||||
virtual std::string TauLclName(void) const { return "TauLcL"; }
|
||||
virtual std::string TauLclName(void) const { return "TauLoc"; }
|
||||
virtual char TauLclShort(void) const { return 'l'; }
|
||||
|
||||
virtual std::string TauGlbName(void) const { return "TauGlb"; }
|
||||
virtual std::string TauGlbName(void) const { return "TauGlob"; }
|
||||
virtual char TauGlbShort(void) const { return 'g'; }
|
||||
|
||||
virtual std::string TauBetaName(void) const { return "Beta"; }
|
||||
|
|
|
|||
|
|
@ -329,13 +329,13 @@ protected:
|
|||
double range; // == 1+2*alpha
|
||||
};
|
||||
|
||||
/** eoArithmeticCrossover --> uniform choice in hypercube
|
||||
/** eoHypercubeCrossover --> uniform choice in hypercube
|
||||
== arithmetical with different values for each coordinate
|
||||
\class eoArithmeticCrossover eoRealOp.h Tutorial/eoRealOp.h
|
||||
\ingroup parameteric
|
||||
*/
|
||||
|
||||
template<class EOT> class eoArithmeticCrossover: public eoQuadOp<EOT>
|
||||
template<class EOT> class eoHypercubeCrossover: public eoQuadOp<EOT>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
|
|
@ -347,7 +347,7 @@ template<class EOT> class eoArithmeticCrossover: public eoQuadOp<EOT>
|
|||
* 0 == contractive application
|
||||
* Must be positive
|
||||
*/
|
||||
eoArithmeticCrossover(const double& _alpha = 0.0):
|
||||
eoHypercubeCrossover(const double& _alpha = 0.0):
|
||||
bounds(eoDummyVectorNoBounds), alpha(_alpha), range(1+2*_alpha)
|
||||
{
|
||||
if (_alpha < 0)
|
||||
|
|
@ -362,7 +362,7 @@ template<class EOT> class eoArithmeticCrossover: public eoQuadOp<EOT>
|
|||
* 0 == contractive application
|
||||
* Must be positive
|
||||
*/
|
||||
eoArithmeticCrossover(eoRealVectorBounds & _bounds,
|
||||
eoHypercubeCrossover(eoRealVectorBounds & _bounds,
|
||||
const double& _alpha = 0.0):
|
||||
bounds(_bounds), alpha(_alpha), range(1+2*_alpha)
|
||||
{
|
||||
|
|
@ -371,10 +371,10 @@ template<class EOT> class eoArithmeticCrossover: public eoQuadOp<EOT>
|
|||
}
|
||||
|
||||
/// The class name.
|
||||
virtual string className() const { return "eoArithmeticCrossover"; }
|
||||
virtual string className() const { return "eoHypercubeCrossover"; }
|
||||
|
||||
/**
|
||||
* arithmetical crossover - modifies both parents
|
||||
* hypercube crossover - modifies both parents
|
||||
* @param _eo1 The first parent
|
||||
* @param _eo2 The first parent
|
||||
*/
|
||||
|
|
@ -434,21 +434,21 @@ protected:
|
|||
\ingroup parameteric
|
||||
*/
|
||||
|
||||
template<class EOT> class eoRealUxOver: public eoQuadOp<EOT>
|
||||
template<class EOT> class eoRealUXover: public eoQuadOp<EOT>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* (Default) Constructor.
|
||||
* @param _preference bias in the choice (usually, no bias == 0.5)
|
||||
*/
|
||||
eoRealUxOver(const float& _preference = 0.5): preference(_preference)
|
||||
eoRealUXover(const float& _preference = 0.5): preference(_preference)
|
||||
{
|
||||
if ( (_preference <= 0.0) || (_preference >= 1.0) )
|
||||
runtime_error("UxOver --> invalid preference");
|
||||
}
|
||||
|
||||
/// The class name.
|
||||
virtual string className() const { return "eoRealUxOver"; }
|
||||
virtual string className() const { return "eoRealUXover"; }
|
||||
|
||||
/**
|
||||
* Uniform crossover for real vectors
|
||||
|
|
|
|||
|
|
@ -130,10 +130,10 @@ eoGenOp<EOT> & do_make_op(eoParameterLoader& _parser, eoState& _state, eoRealIni
|
|||
// crossover
|
||||
/////////////
|
||||
// ES crossover
|
||||
eoValueParam<string>& crossTypeParam = _parser.createParam(string("Global"), "crossType", "Type of ES recombination (gloabl or local)", 'C', "Variation Operators");
|
||||
eoValueParam<string>& crossTypeParam = _parser.createParam(string("global"), "crossType", "Type of ES recombination (global or standard)", 'C', "Variation Operators");
|
||||
|
||||
eoValueParam<string>& crossObjParam = _parser.createParam(string("Discrete"), "crossObj", "Recombination of object variables (Discrete or Intermediate)", 'O', "Variation Operators");
|
||||
eoValueParam<string>& crossStdevParam = _parser.createParam(string("Intermediate"), "crossStdev", "Recombination of mutation strategy parameters (Intermediate or Discrete)", 'S', "Variation Operators");
|
||||
eoValueParam<string>& crossObjParam = _parser.createParam(string("discrete"), "crossObj", "Recombination of object variables (discrete or intermediate)", 'O', "Variation Operators");
|
||||
eoValueParam<string>& crossStdevParam = _parser.createParam(string("intermediate"), "crossStdev", "Recombination of mutation strategy parameters (intermediate or discrete)", 'S', "Variation Operators");
|
||||
|
||||
// The pointers: first the atom Xover
|
||||
eoBinOp<double> *ptObjAtomCross = NULL;
|
||||
|
|
@ -142,22 +142,22 @@ eoGenOp<EOT> & do_make_op(eoParameterLoader& _parser, eoState& _state, eoRealIni
|
|||
eoGenOp<EOT> *ptCross;
|
||||
|
||||
// check for the atom Xovers
|
||||
if (crossObjParam.value() == string("Discrete"))
|
||||
if (crossObjParam.value() == string("discrete"))
|
||||
ptObjAtomCross = new eoRealAtomExchange;
|
||||
else if (crossObjParam.value() == string("Intermediate"))
|
||||
else if (crossObjParam.value() == string("intermediate"))
|
||||
ptObjAtomCross = new eoRealAtomExchange;
|
||||
else throw runtime_error("Invalid Object variable crossover type");
|
||||
|
||||
if (crossStdevParam.value() == string("Discrete"))
|
||||
if (crossStdevParam.value() == string("discrete"))
|
||||
ptStdevAtomCross = new eoRealAtomExchange;
|
||||
else if (crossStdevParam.value() == string("Intermediate"))
|
||||
else if (crossStdevParam.value() == string("intermediate"))
|
||||
ptStdevAtomCross = new eoRealAtomExchange;
|
||||
else throw runtime_error("Invalid mutation strategy parameter crossover type");
|
||||
|
||||
// and build the indi Xover
|
||||
if (crossTypeParam.value() == string("Global"))
|
||||
if (crossTypeParam.value() == string("global"))
|
||||
ptCross = new eoEsGlobalXover<EOT>(*ptObjAtomCross, *ptStdevAtomCross);
|
||||
else if (crossTypeParam.value() == string("Local"))
|
||||
else if (crossTypeParam.value() == string("standard"))
|
||||
ptCross = new eoEsLocalXover<EOT>(*ptObjAtomCross, *ptStdevAtomCross);
|
||||
else throw runtime_error("Invalide Object variable crossover type");
|
||||
|
||||
|
|
|
|||
|
|
@ -131,19 +131,30 @@ eoGenOp<EOT> & do_make_op(eoParameterLoader& _parser, eoState& _state, eoRealIni
|
|||
// the crossovers
|
||||
/////////////////
|
||||
// the parameters
|
||||
eoValueParam<double>& alphaParam = _parser.createParam(double(0.0), "alpha", "Bound for factor of linear recombinations", 'a', "Variation Operators" );
|
||||
// minimum check
|
||||
if ( (alphaParam.value() < 0) )
|
||||
throw runtime_error("Invalid BLX coefficient alpha");
|
||||
|
||||
|
||||
eoValueParam<double>& segmentRateParam = _parser.createParam(double(1.0), "segmentRate", "Relative rate for segment crossover", 's', "Variation Operators" );
|
||||
// minimum check
|
||||
if ( (segmentRateParam.value() < 0) )
|
||||
throw runtime_error("Invalid segmentRate");
|
||||
|
||||
eoValueParam<double>& arithmeticRateParam = _parser.createParam(double(2.0), "arithmeticRate", "Relative rate for arithmetic crossover", 'A', "Variation Operators" );
|
||||
eoValueParam<double>& hypercubeRateParam = _parser.createParam(double(1.0), "hypercubeRate", "Relative rate for hypercube crossover", 'A', "Variation Operators" );
|
||||
// minimum check
|
||||
if ( (arithmeticRateParam.value() < 0) )
|
||||
throw runtime_error("Invalid arithmeticRate");
|
||||
if ( (hypercubeRateParam.value() < 0) )
|
||||
throw runtime_error("Invalid hypercubeRate");
|
||||
|
||||
eoValueParam<double>& uxoverRateParam = _parser.createParam(double(1.0), "uxoverRate", "Relative rate for uniform crossover", 'A', "Variation Operators" );
|
||||
// minimum check
|
||||
if ( (uxoverRateParam.value() < 0) )
|
||||
throw runtime_error("Invalid uxoverRate");
|
||||
|
||||
// minimum check
|
||||
bool bCross = true;
|
||||
if (segmentRateParam.value()+arithmeticRateParam.value()==0)
|
||||
if (segmentRateParam.value()+hypercubeRateParam.value()+uxoverRateParam.value()==0)
|
||||
{
|
||||
cerr << "Warning: no crossover" << endl;
|
||||
bCross = false;
|
||||
|
|
@ -156,14 +167,19 @@ eoGenOp<EOT> & do_make_op(eoParameterLoader& _parser, eoState& _state, eoRealIni
|
|||
if (bCross)
|
||||
{
|
||||
// segment crossover for bitstring - pass it the bounds
|
||||
ptQuad = new eoSegmentCrossover<EOT>(*ptBounds);
|
||||
ptQuad = new eoSegmentCrossover<EOT>(*ptBounds, alphaParam.value());
|
||||
_state.storeFunctor(ptQuad);
|
||||
ptCombinedQuadOp = new eoPropCombinedQuadOp<EOT>(*ptQuad, segmentRateParam.value());
|
||||
|
||||
// arithmetic crossover
|
||||
ptQuad = new eoArithmeticCrossover<EOT>(*ptBounds);
|
||||
// hypercube crossover
|
||||
ptQuad = new eoHypercubeCrossover<EOT>(*ptBounds, alphaParam.value());
|
||||
_state.storeFunctor(ptQuad);
|
||||
ptCombinedQuadOp->add(*ptQuad, arithmeticRateParam.value());
|
||||
ptCombinedQuadOp->add(*ptQuad, hypercubeRateParam.value());
|
||||
|
||||
// uniform crossover
|
||||
ptQuad = new eoRealUXover<EOT>();
|
||||
_state.storeFunctor(ptQuad);
|
||||
ptCombinedQuadOp->add(*ptQuad, uxoverRateParam.value());
|
||||
|
||||
// don't forget to store the CombinedQuadOp
|
||||
_state.storeFunctor(ptCombinedQuadOp);
|
||||
|
|
|
|||
|
|
@ -1,22 +1,9 @@
|
|||
#include <ctime>
|
||||
#include "eoRNG.h"
|
||||
|
||||
#include <sys/time.h>
|
||||
/** this function retunrs a "truly random" seed for RNG
|
||||
* Replaces the call to time(0) that seems to be non-portable???
|
||||
*/
|
||||
uint32 random_seed()
|
||||
{
|
||||
struct timeval tval;
|
||||
struct timezone tzp;
|
||||
|
||||
gettimeofday (&tval, &tzp); // milliseconds since midnight January 1, 1970.
|
||||
return uint32(tval.tv_usec);
|
||||
}
|
||||
|
||||
namespace eo
|
||||
{
|
||||
/// The Global random number generator.
|
||||
eoRng rng(random_seed());
|
||||
eoRng rng(time(0));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -288,9 +288,6 @@ extern eoRng rng;
|
|||
|
||||
using eo::rng;
|
||||
|
||||
/** the random_seed utility in eoRNG.cpp */
|
||||
extern uint32 random_seed();
|
||||
|
||||
// Implementation of some eoRng members.... Don't mind the mess, it does work.
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
#include <utils/eoParser.h>
|
||||
#include <fstream.h>
|
||||
#include <stdexcept>
|
||||
|
||||
/** Generation of the status file, and output of the help message if needed
|
||||
*
|
||||
|
|
@ -60,3 +61,40 @@ void make_help(eoParser & _parser)
|
|||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/** test a dir.
|
||||
* Creates it if does not exist
|
||||
* If exists, throws an exception or erase everything there,
|
||||
* depending on last parameter
|
||||
*
|
||||
* Always return true (for code easy writing on the other side :-)
|
||||
*/
|
||||
bool testDirRes(std::string _dirName, bool _erase)
|
||||
{
|
||||
string s = "test -d " + _dirName;
|
||||
int res = system(s.c_str());
|
||||
// test for (unlikely) errors
|
||||
if ( (res==-1) || (res==127) )
|
||||
{
|
||||
s = "Problem executing test of dir " + _dirName;
|
||||
throw runtime_error(s);
|
||||
}
|
||||
// now make sure there is a dir without any file in it - or quit
|
||||
if (res) // no dir present
|
||||
{
|
||||
s = string("mkdir ")+ _dirName;
|
||||
system(s.c_str());
|
||||
return true;
|
||||
}
|
||||
// else
|
||||
if (_erase) // OK to erase
|
||||
{
|
||||
s = string("/bin/rm ")+ _dirName + "/*";
|
||||
system(s.c_str());
|
||||
return true;
|
||||
}
|
||||
//else
|
||||
s = "Dir " + _dirName + " is not empty";
|
||||
throw runtime_error(s);
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
Reference in a new issue