00001
00002 #include <eo>
00003
00004
00005 #include <eoNDSorting.h>
00006 #include <eoParetoFitness.h>
00007
00008 using namespace std;
00009
00010
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
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
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
00141
00142 if (what > 2)
00143 {
00144 std::cout << "Warning, need an integer < 3 for perf2worth" << std::endl;
00145
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
00164
00165 return state.storeFunctor(new eoDetTournamentWorthSelect<eoDouble>(perf2worth, tournamentsize));
00166 }
00167
00168
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
00183 eoPerf2Worth<eoDouble, double>& perf2worth = make_perf2worth<eoDouble>(parser, state);
00184
00185
00186 eoSelectOne<eoDouble>& select = make_selector<eoDouble>(parser, state, perf2worth);
00187
00188
00189 eoProportionalOp<eoDouble> opsel;
00190 opsel.add(mutate, 1.0);
00191
00192
00193 eoGeneralBreeder<eoDouble> breeder(select, opsel);
00194
00195
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
00210
00211 cp.add(snapshot);
00212
00213 snapshot.add(fitness0);
00214 snapshot.add(fitness1);
00215
00216
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;
00240 }
00241 }
00242
00243
00244
00245
00246
00247
00248