ECF 1.5
SymbRegEvalOp.cpp
1#include <cmath>
2#include <ecf/ECF.h>
3#include "SymbRegEvalOp.h"
4#include "infixTree.h"
5
6extern bool evaluateVerbose;
7
8
9// called only once, before the evolution – generates training data
10bool SymbRegEvalOp::initialize(StateP state)
11{
12 state_ = state;
13
14 x.clear();
15 y.clear();
16
17 // circle
18 nSamples = 40;
19 double s = -1;
20 for(uint i = 0; i < nSamples / 2; i++) {
21 x.push_back(s);
22 y.push_back(sqrt(1 - s*s));
23 x.push_back(s);
24 y.push_back(-1 * sqrt(1 - s*s));
25 s += 0.1;
26 }
27
28 // elliptic
29 //double t = 1;
30 //for(uint i = 0; i < 30; i++) {
31 // x.push_back(t);
32 // y.push_back(sqrt(t*t*t + t - 1.5));
33 // x.push_back(t);
34 // y.push_back(-1 * sqrt(t*t*t + t - 1.5));
35 // t += 0.1;
36 //}
37 //nSamples = x.size();
38
39 return true;
40}
41
42
43FitnessP SymbRegEvalOp::evaluate(IndividualP individual)
44{
45 // we try to minimize the function value, so we use FitnessMin fitness (for minimization problems)
46 FitnessP fitness (new FitnessMin);
47
48 // get the genotype we defined in the configuration file
49 Tree::Tree* tree = (Tree::Tree*) individual->getGenotype().get();
50
51 // test for variables
52 bool foundX = false, foundY = false;
53 for(uint i = 0; i < tree->size(); i++) {
54 std::string prim = tree->at(i)->primitive_->getName();
55 if(prim == "x")
56 foundX = true;
57 if(prim == "y")
58 foundY = true;
59 }
60 if(!foundX || !foundY) {
61 fitness->setValue(nSamples * nSamples * nSamples);
62 return fitness;
63 }
64
65 // test for constant value
66 uint testSize = 20;
67 std::vector<double> testValues(testSize);
68 double result;
69 for(uint i = 0; i < testSize; i++) {
70 // shpere R = 1
71 double x = - 1 + 2 * state_->getRandomizer()->getRandomDouble();
72 double y = - 1 + 2 * state_->getRandomizer()->getRandomDouble();
73
74 // elliptic
75 //double x = 1 + 3 * state_->getRandomizer()->getRandomDouble();
76 //double y = 1 + 7 * state_->getRandomizer()->getRandomDouble();
77
78 tree->setTerminalValue("x", &x);
79 tree->setTerminalValue("y", &y);
80 tree->execute(&result);
81 testValues[i] = result;
82 }
83 double testDev = getStdDev(testValues);
84 if(testDev < 1e-6) {
85 fitness->setValue(nSamples * nSamples * nSamples);
86 return fitness;
87 }
88
89 std::vector<double> values(nSamples);
90 double average = 0;
91 for(uint i = 0; i < nSamples; i++) {
92 // for each test data instance, the x value (domain) must be set
93 tree->setTerminalValue("x", &x[i]);
94 tree->setTerminalValue("y", &y[i]);
95 // get the y value of the current tree
96 double result;
97 tree->execute(&result);
98 values[i] = result;
99 average += result;
100 }
101 average /= nSamples;
102
103 double dev = 0;
104 for(uint i = 0; i < nSamples; i++) {
105 // add the difference
106 dev += (values[i] - average) * (values[i] - average);
107 }
108 dev = sqrt(dev / (nSamples - 1));
109
110 fitness->setValue(dev);
111
112 if(evaluateVerbose) {
113 std::string infix;
114 showTree(infix, tree);
115 ECF_LOG_ERROR(state_, infix);
116
117 ofstream outmap("outmap.txt");
118 for(double x = -1; x <= 1; x += 0.1) {
119 for(double y = -1; y <= 1; y += 0.1) {
120 tree->setTerminalValue("x", &x);
121 tree->setTerminalValue("y", &y);
122 tree->execute(&result);
123 outmap << result << "\t";
124 }
125 outmap << endl;
126 }
127 outmap.close();
128
129 ofstream outval("values.txt");
130 for(uint i = 0; i < values.size(); i++) {
131 outval << values[i] << endl;
132 }
133 outval.close();
134 }
135
136 return fitness;
137}
138
139
140double SymbRegEvalOp::getMean(vector<double>& values)
141{
142 double sum = 0;
143 for(uint i = 0; i < values.size(); i++)
144 sum += values[i];
145 return sum / values.size();
146}
147
148
149double SymbRegEvalOp::getStdDev(vector<double>& values)
150{
151 if(values.size() == 0)
152 return 0;
153 double numerator = 0, denominator;
154 double average = getMean(values);
155 for(uint i = 0; i < values.size(); i++) {
156 numerator += ((values[i] - average) * (values[i] - average));
157 }
158 denominator = (values.size() - 1);
159 return sqrt(numerator / denominator);
160}
Fitness for minimization problems.
Definition: FitnessMin.h:12
std::string getName()
Return genotype's name (each genotype is uniquely identified with its name).
Definition: Genotype.h:86
FitnessP evaluate(IndividualP individual)
Evaluate a single individual. Method must create and return a Fitness object.
bool initialize(StateP)
Initialize the evaluator. Called before first evaluation occurs.
Tree class - implements genotype as a tree.
Definition: Tree_c.h:29
void setTerminalValue(std::string, void *)
Set a terminal's value.
Definition: Tree.cpp:504
void execute(void *)
Execute current tree.
Definition: Tree.cpp:362