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