00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef gprop_h
00027 #define gprop_h
00028
00029
00030
00031 #include <iostream>
00032 #include <iomanip>
00033 #include <string>
00034 #include <EO.h>
00035 #include <eoOp.h>
00036 #include <eoInit.h>
00037 #include <utils/rnd_generators.h>
00038 #include "mlp.h"
00039 #include "qp.h"
00040 #include "mse.h"
00041
00042
00043
00044
00045
00046 struct phenotype
00047 {
00048 int trn_ok, val_ok, tst_ok;
00049 double mse_error;
00050
00051 static int trn_max, val_max, tst_max;
00052
00053 friend bool operator<(const phenotype& a, const phenotype& b)
00054 {
00055 return (a.val_ok < b.val_ok) || (!(b.val_ok < a.val_ok)) && (b.mse_error < a.mse_error);
00056 }
00057
00058 friend bool operator==(const phenotype& a, const phenotype& b)
00059 {
00060 return (a.val_ok == b.val_ok) && (b.mse_error == a.mse_error);
00061 }
00062
00063 friend bool operator>=(const phenotype& a, const phenotype& b)
00064 {
00065 return !(a < b);
00066 }
00067
00068 friend bool operator>(const phenotype& a, const phenotype& b)
00069 {
00070 return (!(a == b)) && (!(a < b));
00071 }
00072
00073
00074
00075 friend std::ostream& operator<<(std::ostream& os, const phenotype& p)
00076 {
00077 return os << p.trn_ok << "/" << p.trn_max << " "
00078 << p.val_ok << "/" << p.val_max << " "
00079 << p.tst_ok << "/" << p.tst_max << " "
00080 << p.mse_error;
00081 }
00082
00083 friend std::istream& operator>>(std::istream& is, phenotype& p)
00084 {
00085 return is;
00086 }
00087 };
00088
00089
00090 int phenotype::trn_max = 0, phenotype::val_max = 0, phenotype::tst_max = 0;
00091
00092
00093
00094
00095 #ifndef GPROP_GENOTYPE
00096 #define GPROP_GENOTYPE mlp::net
00097 #endif
00098
00099 typedef GPROP_GENOTYPE genotype;
00100
00101
00102
00103
00104
00105 extern unsigned in, out, hidden;
00106
00107 class Chrom: public EO<phenotype>, public genotype
00108 {
00109 public:
00110 Chrom(): genotype(in, out, std::vector<unsigned>(hidden < 1 ? 0 : 1, hidden)) {}
00111
00112 std::string className() const { return "Chrom"; }
00113
00114 void printOn (std::ostream& os) const
00115 {
00116 os << std::setprecision(3) << static_cast<genotype>(*this) << " \t"
00117 << fitness();
00118
00119 }
00120
00121 void readFrom (std::istream& is)
00122 {
00123 invalidate();
00124 }
00125 };
00126
00127
00128
00129
00130
00131 class eoInitChrom: public eoInit<Chrom>
00132 {
00133 public:
00134 void operator()(Chrom& chrom)
00135 {
00136 chrom.reset();
00137 chrom.invalidate();
00138 }
00139 };
00140
00141
00142
00143
00144
00145 mlp::set *trn_set = 0, *val_set = 0, *tst_set = 0;
00146
00147 void gprop_use_datasets(mlp::set *trn, mlp::set *val, mlp::set *tst) {
00148 trn_set = trn;
00149 val_set = val;
00150 tst_set = tst;
00151 }
00152
00153 void ensure_datasets_initialized() {
00154 if (!trn_set) {
00155 std::cerr << "trn_set is not initialized. Must call gprop_use_datasets before training\n";
00156 std::cerr.flush();
00157 abort();
00158 }
00159 }
00160
00161
00162
00163
00164
00165 class eoChromMutation: public eoMonOp<Chrom>
00166 {
00167 public:
00168 bool operator()(Chrom& chrom)
00169 {
00170 mse::net tmp(chrom);
00171 tmp.train(*trn_set, 10, 0, 0.001);
00172 return true;
00173 }
00174 };
00175
00176
00177
00178
00179
00180 class eoChromXover: public eoQuadOp<Chrom>
00181 {
00182 public:
00183 bool operator()(Chrom& chrom1, Chrom& chrom2)
00184 {
00185 chrom1.normalize();
00186 chrom2.desaturate();
00187
00188 mse::net tmp1(chrom1), tmp2(chrom2);
00189 ensure_datasets_initialized();
00190 tmp1.train(*trn_set, 100, 0, 0.001);
00191 tmp2.train(*trn_set, 100, 0, 0.001);
00192
00193 return true;
00194 }
00195 };
00196
00197
00198
00199
00200
00201 int correct(const mlp::net& net, const mlp::set& set)
00202 {
00203 int sum = 0;
00204
00205 for (mlp::set::const_iterator s = set.begin(); s != set.end(); ++s)
00206 {
00207 unsigned partial = 0;
00208
00209 for (unsigned i = 0; i < s->output.size(); ++i)
00210 if (s->output[i] < 0.5 && net(s->input)[i] < 0.5 ||
00211 s->output[i] > 0.5 && net(s->input)[i] > 0.5)
00212 ++partial;
00213
00214 if (partial == s->output.size())
00215 ++sum;
00216 }
00217
00218 return sum;
00219 }
00220
00221 phenotype eoChromEvaluator(const Chrom& chrom)
00222 {
00223 phenotype p;
00224 ensure_datasets_initialized();
00225 p.trn_ok = correct(chrom, *trn_set);
00226 p.val_ok = correct(chrom, *val_set);
00227 p.tst_ok = correct(chrom, *tst_set);
00228 p.mse_error = mse::error(chrom, *val_set);
00229
00230 return p;
00231 }
00232
00233
00234
00235 #endif // gprop_h
00236
00237
00238
00239