00001
00002
00003
00004
00005 #ifndef mastermind_h
00006 #define mastermind_h
00007
00008
00009
00010 #include <stdlib.h>
00011 #include <eoVector.h>
00012 #include <eoOp.h>
00013 #include <eoInit.h>
00014 #include "utils/rnd_generators.h"
00015
00016
00017
00018
00019
00020 typedef float phenotype;
00021
00022
00023
00024
00025
00026 typedef std::vector<int> genotype;
00027
00028
00029
00030
00031
00032 typedef eoVector<phenotype, int> Chrom;
00033
00034
00035
00036
00037
00038
00039 Chrom solution;
00040
00041 phenotype eoChromEvaluator(const Chrom& chrom)
00042 {
00043 Chrom tmp = solution;
00044 unsigned black = 0, white = 0;
00045
00046
00047 for (unsigned i = 0; i < chrom.size(); ++i)
00048 if (chrom[i] == tmp[i])
00049 {
00050 ++black;
00051 tmp[i] = -1;
00052 }
00053
00054
00055 for (unsigned i = 0; i < chrom.size(); ++i)
00056 for (unsigned j = 0; j < tmp.size(); ++j)
00057 if (chrom[i] == tmp[j])
00058 {
00059 ++white;
00060 tmp[j] = -1;
00061 break;
00062 }
00063
00064
00065 return black * chrom.size() + white;
00066 }
00067
00068 const unsigned default_length = 8;
00069 const unsigned default_colors = 8;
00070 const std::string default_solution = "01234567";
00071
00072
00073 unsigned num_colors;
00074
00075 void init_eoChromEvaluator(const unsigned& c, const unsigned& l, std::string s)
00076 {
00077 num_colors = c;
00078
00079
00080 if (s != default_solution)
00081 {
00082
00083 if (l != default_length && s.size() != l)
00084 {
00085 std::cerr << "solution length != length" << std::endl;
00086 exit(EXIT_FAILURE);
00087 }
00088
00089
00090 if ((c != default_colors) && (c < unsigned(*max_element(s.begin(), s.end()) - '0')))
00091 {
00092 std::cerr << "too high color number found!" << std::endl;
00093 exit(EXIT_FAILURE);
00094 }
00095 }
00096 else
00097 if (l != default_length || c != default_colors )
00098
00099 if(num_colors <= 10)
00100 {
00101 uniform_generator<char> color('0', static_cast<char>('0' + c));
00102 s.resize(l);
00103 generate(s.begin(), s.end(), color);
00104 }
00105
00106
00107 if (num_colors <= 10)
00108 {
00109 solution.resize(s.size());
00110 for (unsigned i = 0; i < solution.size(); ++i)
00111 solution[i] = s[i] - '0';
00112 }
00113 else
00114 {
00115 solution.resize(l);
00116 uniform_generator<int> color(0, num_colors);
00117 generate(solution.begin(), solution.end(), color);
00118 }
00119
00120 solution.fitness(eoChromEvaluator(solution));
00121 }
00122
00123
00124
00125
00126
00127 class eoInitChrom: public eoInit<Chrom>
00128 {
00129 public:
00130 void operator()(Chrom& chrom)
00131 {
00132 uniform_generator<int> color(0, num_colors);
00133 chrom.resize(solution.size());
00134 generate(chrom.begin(), chrom.end(), color);
00135 chrom.invalidate();
00136 }
00137 };
00138
00139
00140
00141
00142
00143 class eoChromMutation: public eoMonOp<Chrom>
00144 {
00145
00146 bool operator()(Chrom& chrom)
00147 {
00148 uniform_generator<unsigned> what(0, 2);
00149 uniform_generator<unsigned> position(0, chrom.size());
00150
00151 switch(what())
00152 {
00153 case 0:
00154 {
00155
00156 uniform_generator<int> color(0, num_colors);
00157 chrom[position()] = color();
00158 break;
00159 }
00160 case 1:
00161 {
00162
00163 std::swap(chrom[position()], chrom[position()]);
00164 break;
00165 }
00166 default:
00167 {
00168 std::cerr << "unknown operator!" << std::endl;
00169 exit(EXIT_FAILURE);
00170 break;
00171 }
00172 }
00173
00174 return true;
00175 }
00176 };
00177
00178
00179
00180
00181
00182 class eoChromXover: public eoQuadOp<Chrom>
00183 {
00184 public:
00185 bool operator()(Chrom& chrom1, Chrom& chrom2)
00186 {
00187 uniform_generator<unsigned> position(0, chrom1.size());
00188 swap_ranges(chrom1.begin(), chrom1.begin() + position(), chrom2.begin());
00189 return true;
00190 }
00191 };
00192
00193
00194
00195 #endif // mastermind_h
00196
00197
00198
00199