# t-eoPareto.cpp

    00001
    00002 #include <eo>
    00003
    00004 //#include <utils/eoMOFitnessStat.h>
    00005 #include <eoNDSorting.h>
    00006 #include <eoParetoFitness.h>
    00007
    00008 using namespace std;
    00009
    00010 // Look: overloading the maximization without overhead (thing can be inlined)
    00011 class MinimizingFitnessTraits : public eoParetoFitnessTraits
    00012 {
    00013   public :
    00014   static bool maximizing(int) { return false; }
    00015 };
    00016
    00017 typedef eoParetoFitness<MinimizingFitnessTraits> fitness_type;
    00018
    00019 const unsigned chromsize=3;
    00020 const double minval = -5;
    00021 const double maxval = 5;
    00022
    00023 struct eoDouble : public EO<fitness_type>
    00024 {
    00025   double value[chromsize];
    00026 };
    00027
    00028 class Mutate : public eoMonOp<eoDouble>
    00029 {
    00030   bool operator()(eoDouble& _eo)
    00031   {
    00032     for (unsigned i = 0; i < chromsize; ++i)
    00033     {
    00034       if (rng.flip(1./chromsize))
    00035         _eo.value[i] += rng.normal() * 0.1 * _eo.value[i];
    00036
    00037       if (_eo.value[i] < minval)
    00038         _eo.value[i] = minval;
    00039       else if (_eo.value[i] > maxval)
    00040         _eo.value[i] = maxval;
    00041     }
    00042
    00043     return true;
    00044   }
    00045 };
    00046
    00047 class Eval : public eoEvalFunc<eoDouble>
    00048 {
    00049   void operator()(eoDouble& _eo)
    00050   {
    00051     vector<double> x(_eo.value, _eo.value + chromsize);
    00052     fitness_type f;
    00053
    00054     for (unsigned i = 0; i < chromsize; ++i)
    00055     {
    00056       if (i < chromsize-1)
    00057       {
    00058         f[0] += -10.0 * exp(-0.2 * sqrt(x[i]*x[i] + x[i+1]*x[i+1]));
    00059       }
    00060
    00061       f[1] += pow(fabs(x[i]), 0.8) + 5 * pow(sin(x[i]),3.);
    00062     }
    00063
    00064     _eo.fitness(f);
    00065   }
    00066 };
    00067
    00068 class Init : public eoInit<eoDouble>
    00069 {
    00070   void operator()(eoDouble& _eo)
    00071   {
    00072     _eo.value[0] = rng.uniform();
    00073
    00074     double range = maxval - minval;
    00075
    00076     for (unsigned i = 1; i < chromsize; ++i)
    00077       _eo.value[i] = rng.uniform() * range + minval;
    00078     _eo.invalidate();
    00079   }
    00080 };
    00081
    00086 template <class EOT, class WorthT = double>
    00087 class eoNDPlusReplacement : public eoReplacement<EOT>
    00088 {
    00089 public:
    00090
    00091     // using eoNDPlusReplacement< EOT, WorthT >::first;
    00092
    00093     eoNDPlusReplacement(eoPerf2Worth<EOT, WorthT>& _perf2worth)
    00094         : perf2worth(_perf2worth)
    00095         {}
    00096
    00097     struct WorthPair : public pair<WorthT, const EOT*>
    00098     {
    00099         bool operator<(const WorthPair& other) const
    00100             { return other.first < this->first; }
    00101     };
    00102
    00103
    00104   void operator()(eoPop<EOT>& _parents, eoPop<EOT>& _offspring)
    00105   {
    00106     unsigned sz = _parents.size();
    00107     _parents.reserve(_parents.size() + _offspring.size());
    00108     std::copy(_offspring.begin(), _offspring.end(), back_inserter(_parents));
    00109
    00110     // calculate worths
    00111     perf2worth(_parents);
    00112     perf2worth.sort_pop(_parents);
    00113     perf2worth.resize(_parents, sz);
    00114
    00115     _offspring.clear();
    00116   }
    00117
    00118 private :
    00119     eoPerf2Worth<EOT, WorthT>& perf2worth;
    00120 };
    00121
    00122 template <class EOT>
    00123 eoPerf2Worth<EOT, double>& make_perf2worth(eoParser& parser, eoState& state)
    00124 {
    00125
    00126   unsigned what = parser.createParam(unsigned(1), "perf2worth", "worth mapping indicator : \n\t \
    00127                   0: non_dominated sorting \n\t\
    00128                   1: non_dominated sorting 2 \n\t\
    00129                   2: simple ranking \n\t", 'w').value();
    00130
    00131   switch (what)
    00132   {
    00133     case 1 : return state.storeFunctor(new eoNDSorting_II<EOT>());
    00134     case 2 :
    00135     {
    00136       eoDominanceMap<eoDouble>&  dominance = state.storeFunctor(new eoDominanceMap<EOT>);
    00137       return state.storeFunctor(new eoParetoRanking<EOT>(dominance));
    00138     }
    00139   }
    00140   //default
    00141
    00142   if (what > 2)
    00143   {
    00144     std::cout << "Warning, need an integer < 3 for perf2worth" << std::endl;
    00145     // should actually set parser flag, but I don't care
    00146   }
    00147
    00148   return state.storeFunctor(new eoNDSorting_I<EOT>(0.5));
    00149 }
    00150
    00151 template <class EOT>
    00152 eoSelectOne<EOT>& make_selector(eoParser& parser, eoState& state, eoPerf2Worth<EOT, double>& perf2worth)
    00153 {
    00154   unsigned tournamentsize = parser.createParam(unsigned(2), "tournament_size", "Tournament Size", 't').value();
    00155   double stochtour = parser.createParam(unsigned(0.95), "tournament_prob", "Probability in stochastic tournament").value();
    00156
    00157   switch (parser.createParam(unsigned(0), "selector", "Which selector (too lazy to explain: use the source)", 's').value())
    00158   {
    00159     case 1 : return state.storeFunctor(new eoStochTournamentWorthSelect<eoDouble>(perf2worth, stochtour));
    00160     case 2 : return state.storeFunctor(new eoRouletteWorthSelect<eoDouble>(perf2worth));
    00161     case 3 : return state.storeFunctor(new eoRandomSelect<EOT>);
    00162   }
    00163   // default
    00164
    00165   return state.storeFunctor(new eoDetTournamentWorthSelect<eoDouble>(perf2worth, tournamentsize));
    00166 }
    00167
    00168 // Test pareto dominance and perf2worth, and while you're at it, test the eoGnuPlot monitor as well
    00169 void the_main(int argc, char* argv[])
    00170 {
    00171   Init init;
    00172   Eval eval;
    00173   Mutate mutate;
    00174
    00175   eoParser parser(argc, argv);
    00176   eoState state;
    00177
    00178   unsigned num_gen  = parser.createParam(unsigned(50), "num_gen", "number of generations to run", 'g').value();
    00179   unsigned pop_size = parser.createParam(unsigned(100), "pop_size", "population size", 'p').value();
    00180   eoPop<eoDouble> pop(pop_size, init);
    00181
    00182   // Look, a factory function
    00183   eoPerf2Worth<eoDouble, double>& perf2worth = make_perf2worth<eoDouble>(parser, state);
    00184
    00185   // Look: another factory function, now for selection
    00186   eoSelectOne<eoDouble>& select = make_selector<eoDouble>(parser, state, perf2worth);
    00187
    00188   // One general operator
    00189   eoProportionalOp<eoDouble> opsel;
    00190   opsel.add(mutate, 1.0);
    00191
    00192   // the breeder
    00193   eoGeneralBreeder<eoDouble> breeder(select, opsel);
    00194
    00195   // replacement
    00196   eoNDPlusReplacement<eoDouble> replace(perf2worth);
    00197
    00198   unsigned long generation = 0;
    00199   eoGenContinue<eoDouble> gen(num_gen, generation);
    00200   eoCheckPoint<eoDouble> cp(gen);
    00201
    00202   eoMOFitnessStat<eoDouble> fitness0(0, "FirstObjective");
    00203   eoMOFitnessStat<eoDouble> fitness1(1, "SecondObjective");
    00204
    00205   cp.add(fitness0);
    00206   cp.add(fitness1);
    00207
    00208   eoGnuplot1DSnapshot snapshot("pareto");
    00209   //snapshot.with(eoGnuplot::Points(3));
    00210
    00211   cp.add(snapshot);
    00212
    00213   snapshot.add(fitness0);
    00214   snapshot.add(fitness1);
    00215
    00216   // the algo
    00217   eoEasyEA<eoDouble> ea(cp, eval, breeder, replace);
    00218
    00219   if (parser.userNeedsHelp())
    00220   {
    00221     parser.printHelp(std::cout);
    00222     return;
    00223   }
    00224
    00225   apply<eoDouble>(eval, pop);
    00226   ea(pop);
    00227 }
    00228
    00229
    00230 int main(int argc, char* argv[])
    00231 {
    00232   try
    00233   {
    00234     the_main(argc, argv);
    00235   }
    00236   catch (std::exception& e)
    00237   {
    00238     std::cout << "Exception thrown: " << e.what() << std::endl;
    00239     throw e; // make sure it does not pass the test
    00240   }
    00241 }
    00242
    00243
    00244
    00245 // Local Variables:
    00246 // mode: C++
    00247 // c-file-style: "Stroustrup"
    00248 // End: