diff --git a/eo/test/Makefile.am b/eo/test/Makefile.am index 87a19a0c..5fc497d8 100644 --- a/eo/test/Makefile.am +++ b/eo/test/Makefile.am @@ -43,7 +43,8 @@ check_PROGRAMS = t-eoParetoFitness \ t-eoRNG \ t-eoEasyPSO \ t-eoNSGA \ - t-eoFrontSorter + t-eoFrontSorter \ + t-eoEpsMOEA TESTS = $(check_PROGRAMS) \ run_tests # This script can be used to check command-line arguments @@ -100,4 +101,5 @@ t_eoSecondsElapsedContinue_SOURCES = t-eoSecondsElapsedContinue.cpp t_eoEasyPSO_SOURCES = t-eoEasyPSO.cpp t_eoNSGA_SOURCES = t-eoNSGA.cpp t_eoFrontSorter_SOURCES = t-eoFrontSorter.cpp +t_eoEpsMOEA_SOURCES = t-eoEpsMOEA.cpp diff --git a/eo/test/t-eoEpsMOEA.cpp b/eo/test/t-eoEpsMOEA.cpp new file mode 100644 index 00000000..7f6f40ba --- /dev/null +++ b/eo/test/t-eoEpsMOEA.cpp @@ -0,0 +1,211 @@ + +#include + +#include + +using namespace std; + +class MinimizingFitnessTraits +{ + public : + static unsigned nObjectives() { return 2; } + static double direction(unsigned) { return -1; } + static double tol() { return 1e-9; } + + static vector eps; +}; + +vector MinimizingFitnessTraits::eps(2, 0.1); + +typedef eoMOFitness fitness_type; + +const unsigned chromsize=5; +const double minval = -15; +const double maxval = 15; + +struct eoDouble : public EO +{ + double value[chromsize]; +}; + +class Mutate : public eoMonOp +{ + bool operator()(eoDouble& _eo) + { + for (unsigned i = 0; i < chromsize; ++i) + { + if (rng.flip(1./chromsize)) { + + _eo.value[i] += rng.normal() * 0.1 * _eo.value[i]; + + if (_eo.value[i] < minval) + _eo.value[i] = minval; + else if (_eo.value[i] > maxval) + _eo.value[i] = maxval; + } + } + return true; + } +}; + +class Cross : public eoBinOp { + + bool operator()(eoDouble& _eo, const eoDouble& eo2) + { + for (unsigned i = 0; i < chromsize; ++i) + { + if (rng.flip(0.5)) { + _eo.value[i] = eo2.value[i]; + } + } + return true; + } + +}; + +class Eval : public eoEvalFunc +{ + void operator()(eoDouble& _eo) + { + vector x(_eo.value, _eo.value + chromsize); + fitness_type f(0.0); + + for (unsigned i = 0; i < chromsize; ++i) + { + if (i < chromsize-1) + { + f[0] += -10.0 * exp(-0.2 * sqrt(x[i]*x[i] + x[i+1]*x[i+1])); + } + + f[1] += pow(fabs(x[i]), 0.8) + 5 * pow(sin(x[i]),3.); + } + + _eo.fitness(f); + } +}; + +class Eval2 : public eoEvalFunc +{ + void operator()(eoDouble& _eo) + { + vector x(_eo.value, _eo.value + chromsize); + fitness_type f; + + for (unsigned i = 0; i < chromsize; ++i) + { + f[0] += x[i] * x[i]; + } + + f[1] = + 3 * x[0] + 2 * x[1] + - x[2]/3 + 0.01*pow(x[3] - x[4], 3); + + _eo.fitness(f); + } +}; + +class Eval3 : public eoEvalFunc +{ + void operator()(eoDouble& _eo) + { + double x = _eo.value[0]; + fitness_type f; + + f[0] = x * x; + double y = x-10; + f[1] = y * y; + + _eo.fitness(f); + } +}; + +class Init : public eoInit +{ + void operator()(eoDouble& _eo) + { + _eo.value[0] = rng.uniform(); + + double range = maxval - minval; + + for (unsigned i = 1; i < chromsize; ++i) + _eo.value[i] = rng.uniform() * range + minval; + _eo.invalidate(); + } +}; + +// Test pareto dominance and perf2worth, and while you're at it, test the eoGnuPlot monitor as well +void the_main(int argc, char* argv[]) +{ + Init init; + Eval eval; + Mutate mutate; + Cross cross; + + eoParser parser(argc, argv); + eoState state; + + unsigned num_gen = parser.createParam(unsigned(50), "num_gen", "number of generations to run", 'g').value(); + unsigned pop_size = parser.createParam(unsigned(100), "pop_size", "population size", 'p').value(); + + eoPop pop(pop_size, init); + + // binary tournament selection + eoDetTournamentSelect select; + + // One general operator + eoProportionalOp opsel; + opsel.add(mutate, 1.0); + opsel.add(cross, 1.0); + + unsigned long generation = 0; + eoGenContinue gen(num_gen, generation); + eoCheckPoint cp(gen); + + eoMOFitnessStat fitness0(0, "FirstObjective"); + eoMOFitnessStat fitness1(1, "SecondObjective"); + + cp.add(fitness0); + cp.add(fitness1); + + eoGnuplot1DSnapshot snapshot("pareto"); + //snapshot.with(eoGnuplot::Points(3)); + + cp.add(snapshot); + + snapshot.add(fitness0); + snapshot.add(fitness1); + + // the algo + eoEpsMOEA ea(cp, eval, opsel, MinimizingFitnessTraits::eps ); + + if (parser.userNeedsHelp()) + { + parser.printHelp(std::cout); + return; + } + + ea(pop); +} + + +int main(int argc, char* argv[]) +{ + the_main(argc, argv); + return 0; + try + { + the_main(argc, argv); + } + catch (std::exception& e) + { + std::cout << "Exception thrown: " << e.what() << std::endl; + throw e; // make sure it does not pass the test + } +} + + + +// Local Variables: +// mode: C++ +// c-file-style: "Stroustrup" +// End: diff --git a/eo/test/t-eoNSGA.cpp b/eo/test/t-eoNSGA.cpp index bc80dbc5..5ff1d7ba 100644 --- a/eo/test/t-eoNSGA.cpp +++ b/eo/test/t-eoNSGA.cpp @@ -8,11 +8,12 @@ using namespace std; -// Look: overloading the maximization without overhead (thing can be inlined) -class MinimizingFitnessTraits : public eoMOFitnessTraits +class MinimizingFitnessTraits { public : - static double maximizing(int) { return -1; } + static unsigned nObjectives() { return 2; } + static double direction(unsigned) { return -1; } + static double tol() { return 1e-9; } }; typedef eoMOFitness fitness_type; @@ -45,12 +46,27 @@ class Mutate : public eoMonOp } }; +class Cross : public eoBinOp { + + bool operator()(eoDouble& _eo, const eoDouble& eo2) + { + for (unsigned i = 0; i < chromsize; ++i) + { + if (rng.flip(0.5)) { + _eo.value[i] = eo2.value[i]; + } + } + return true; + } + +}; + class Eval : public eoEvalFunc { void operator()(eoDouble& _eo) { vector x(_eo.value, _eo.value + chromsize); - fitness_type f; + fitness_type f(0.0); for (unsigned i = 0; i < chromsize; ++i) { @@ -121,6 +137,7 @@ void the_main(int argc, char* argv[]) Init init; Eval simple_eval; Mutate mutate; + Cross cross; eoParser parser(argc, argv); eoState state; @@ -138,6 +155,7 @@ void the_main(int argc, char* argv[]) // One general operator eoProportionalOp opsel; opsel.add(mutate, 1.0); + opsel.add(cross, 1.0); // the breeder eoGeneralBreeder breeder(select, opsel); diff --git a/eo/test/t-eoPareto.cpp b/eo/test/t-eoPareto.cpp index f98a0d96..87bd8e26 100644 --- a/eo/test/t-eoPareto.cpp +++ b/eo/test/t-eoPareto.cpp @@ -16,9 +16,9 @@ class MinimizingFitnessTraits : public eoParetoFitnessTraits typedef eoParetoFitness fitness_type; -const unsigned chromsize=3; -const double minval = -5; -const double maxval = 5; +const unsigned chromsize=5; +const double minval = -15; +const double maxval = 15; struct eoDouble : public EO { @@ -65,6 +65,26 @@ class Eval : public eoEvalFunc } }; +class Eval2 : public eoEvalFunc +{ + void operator()(eoDouble& _eo) + { + vector x(_eo.value, _eo.value + chromsize); + fitness_type f; + + for (unsigned i = 0; i < chromsize; ++i) + { + f[0] += x[i] * x[i]; + } + + f[1] = + 3 * x[0] + 2 * x[1] + - x[2]/3 + 0.01*pow(x[3] - x[4], 3); + + _eo.fitness(f); + } +}; + class Init : public eoInit { void operator()(eoDouble& _eo)