New ES routines
This commit is contained in:
parent
c6589b5951
commit
4c4ce70c04
17 changed files with 1100 additions and 98 deletions
|
|
@ -4,110 +4,145 @@
|
|||
#pragma warning(disable:4786)
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <stdexcept>
|
||||
|
||||
using namespace std;
|
||||
|
||||
#include <utils/eoParser.h>
|
||||
#include <utils/eoState.h>
|
||||
|
||||
// evolution specific
|
||||
#include <utils/eoStat.h>
|
||||
#include <utils/eoFileMonitor.h>
|
||||
|
||||
// population
|
||||
#include <eoPop.h>
|
||||
|
||||
// evaluation specific
|
||||
#include <eoEvalFuncPtr.h>
|
||||
|
||||
// representation specific
|
||||
#include <es/eoESFullChrom.h> // though contained in following
|
||||
//#include <eoESReco.h>
|
||||
//#include <eoESMut.h>
|
||||
//#include <eoESRandomize.h>
|
||||
// this fitness
|
||||
#include <es/evolution_strategies>
|
||||
|
||||
#include "real_value.h" // the sphere fitness
|
||||
|
||||
// Now the main
|
||||
///////////////
|
||||
typedef eoESFullChrom<float> Ind;
|
||||
|
||||
main(int argc, char *argv[]) {
|
||||
// unsigned mu, lambda;
|
||||
// bool comma;
|
||||
typedef double FitT;
|
||||
|
||||
template <class EOT>
|
||||
void runAlgorithm(EOT, eoParser& _parser, eoEsObjectiveBounds& _bounds);
|
||||
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
// Create the command-line parser
|
||||
eoParser parser( argc, argv, "Basic EA for vector<float> with adaptive mutations");
|
||||
|
||||
// Define Parameters and load them
|
||||
eoValueParam<uint32>& seed = parser.createParam(time(0), "seed", "Random number seed");
|
||||
eoValueParam<string>& load_name = parser.createParam("", "Load","Load a state file",'L');
|
||||
eoValueParam<string>& save_name = parser.createParam("", "Save","Saves a state file",'S');
|
||||
|
||||
eoValueParam<uint32>& seed = parser.createParam(static_cast<uint32>(time(0)), "seed", "Random number seed");
|
||||
eoValueParam<string>& load_name = parser.createParam(string(), "Load","Load a state file",'L');
|
||||
eoValueParam<string>& save_name = parser.createParam(string(), "Save","Saves a state file",'S');
|
||||
eoValueParam<bool>& stdevs = parser.createParam(true, "Stdev", "Use adaptive mutation rates", 's');
|
||||
eoValueParam<bool>& corr = parser.createParam(true, "Correl", "Use correlated mutations", 'c');
|
||||
eoValueParam<unsigned>& chromSize = parser.createParam(unsigned(1), "ChromSize", "Number of chromosomes", 'n');
|
||||
eoValueParam<double>& minimum = parser.createParam(-1.e5, "Min", "Minimum for Objective Variables", 'l');
|
||||
eoValueParam<double>& maximum = parser.createParam(1.e5, "Max", "Maximum for Objective Variables", 'h');
|
||||
|
||||
eoState state;
|
||||
state.registerObject(parser);
|
||||
|
||||
if (load_name.value() != "")
|
||||
state.registerObject(parser);
|
||||
rng.reseed(seed.value());
|
||||
|
||||
if (!load_name.value().empty())
|
||||
{ // load the parser. This is only neccessary when the user wants to
|
||||
// be able to change the parameters in the state file by hand.
|
||||
state.load(load_name.value()); // load the parser
|
||||
}
|
||||
|
||||
|
||||
// Evaluation
|
||||
eoEvalFuncPtr<Ind> eval( real_value );
|
||||
state.registerObject(rng);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
// Evolution and population parameters
|
||||
eoScheme<Ind> the_scheme(parser);
|
||||
|
||||
// recombination and mutation operators, reading their parameters from the parser
|
||||
eoESReco<float> MyReco(parser, FirstEO);
|
||||
eoESMutate<float> MyMut(parser, FirstEO);
|
||||
|
||||
// termination conditions read by the parser
|
||||
eoTermVector<Ind> the_terms(parser);
|
||||
|
||||
// Initialization of the population
|
||||
// shoudl be called using the parser, in case you want to read from file(s)
|
||||
eoESRandomize<float> randomize; // an eoESInd randomnizer
|
||||
eoPop<Ind> pop(the_scheme.PopSize(), FirstEO, randomize);
|
||||
// eval(pop); // shoudl we call it from inside the constructor???
|
||||
|
||||
// ALL parmeters have been read: write them out
|
||||
// Writing the parameters on arv[0].status
|
||||
// but of course this can be modified - see the example parser.cpp
|
||||
parser.outputParam();
|
||||
// except the help parameter???
|
||||
if( parser.getBool("-h" , "--help" , "Shows this help")) {
|
||||
parser.printHelp();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
unsigned i, iind;
|
||||
|
||||
|
||||
cout << "Initial population: \n" << endl;
|
||||
for (i = 0; i < pop.size(); ++i) {
|
||||
eval(pop[i]);
|
||||
cout << pop[i].fitness() << "\t" << pop[i] << endl;
|
||||
eoEsObjectiveBounds bounds(chromSize.value(), minimum.value(), maximum.value());
|
||||
|
||||
// Run the appropriate algorithm
|
||||
if (stdevs.value() == false && corr.value == false)
|
||||
{
|
||||
runAlgorithm(eoEsSimple<FitT>() ,parser, bounds);
|
||||
}
|
||||
else if (corr.value() == true)
|
||||
{
|
||||
runAlgorithm(eoEsFull<FitT>(),parser, bounds);
|
||||
}
|
||||
else
|
||||
{
|
||||
runAlgorithm(eoEsStdev<FitT>(), parser, bounds);
|
||||
}
|
||||
|
||||
// the Operators
|
||||
eoSequentialOpHolder <Ind> seqholder;
|
||||
// seqholder.addOp(MyReco, 1.0);
|
||||
seqholder.addOp(MyMut, 1.0);
|
||||
// and save
|
||||
if (!save_name.value().empty())
|
||||
{
|
||||
string file_name = save_name.value();
|
||||
save_name.value() = ""; // so that it does not appear in the parser section of the state file
|
||||
state.save(file_name);
|
||||
}
|
||||
|
||||
// One generation
|
||||
eoEvolStep<Ind> evol_scheme(the_scheme, seqholder, eval);
|
||||
|
||||
// the algorithm:
|
||||
eoFullEA<Ind> ea(evol_scheme, the_terms);
|
||||
|
||||
ea(pop);
|
||||
|
||||
cout << "Final population: \n" << endl;
|
||||
for (i = 0; i < pop.size(); ++i)
|
||||
cout << pop[i].fitness() << "\t" << pop[i] << endl;
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <class EOT>
|
||||
void runAlgorithm(EOT, eoParser& _parser, eoEsObjectiveBounds& _bounds)
|
||||
{
|
||||
// evaluation
|
||||
eoEvalFuncPtr<eoEsBase<FitT> > eval( real_value );
|
||||
|
||||
// population parameters, unfortunately these can not be altered in the state file
|
||||
eoValueParam<unsigned> mu = _parser.createParam(unsigned(50), "mu","Size of the population");
|
||||
eoValueParam<unsigned>lambda = _parser.createParam(unsigned(250), "lambda", "No. of children to produce");
|
||||
|
||||
if (mu.value() > lambda.value())
|
||||
{
|
||||
throw logic_error("Mu must be smaller than lambda in a comma strategy");
|
||||
}
|
||||
|
||||
// Initialization
|
||||
eoEsChromInit<EOT> init(_bounds);
|
||||
eoPop<EOT> pop(mu.value(), init);
|
||||
|
||||
// evaluate initial population
|
||||
eval.range(pop.begin(), pop.end());
|
||||
|
||||
// Ok, time to set up the algorithm
|
||||
// Proxy for the mutation parameters
|
||||
eoEsMutationInit mutateInit(_parser);
|
||||
|
||||
eoEsMutate<EOT> mutate(mutateInit, _bounds);
|
||||
|
||||
// monitoring, statistics etc.
|
||||
eoAverageStat<EOT> average;
|
||||
eoFileMonitor monitor("test.csv");
|
||||
|
||||
monitor.add(average);
|
||||
|
||||
// Okok, I'm lazy, here's the algorithm defined inline
|
||||
|
||||
for (unsigned i = 0; i < 20; ++i)
|
||||
{
|
||||
pop.resize(pop.size() + lambda.value());
|
||||
|
||||
for (unsigned j = mu.value(); j < pop.size(); ++j)
|
||||
{
|
||||
pop[j] = pop[rng.random(mu.value())];
|
||||
mutate(pop[j]);
|
||||
eval(pop[j]);
|
||||
}
|
||||
|
||||
// comma strategy
|
||||
std::sort(pop.begin() + mu.value(), pop.end());
|
||||
copy(pop.begin() + mu.value(), pop.begin() + 2 * mu.value(), pop.begin());
|
||||
pop.resize(mu.value());
|
||||
|
||||
average(pop);
|
||||
monitor();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue