ECF 1.5
main_moj.cpp
1#include <ecf/ECF.h>
2
3
4
6// the evaluation operator
7//
8class PrimeEvalOp : public EvaluateOp
9{
10public:
11 FitnessP evaluate(IndividualP individual);
12 bool initialize(StateP);
13 std::vector<int> domain;
14 std::vector<int> codomain;
15 uint nSamples;
16};
17
18
19// called only once, before the evolution – reads training data
20bool PrimeEvalOp::initialize(StateP state)
21{
22 // open data
23 ifstream input("list.txt");
24 // how many samples
25 nSamples = 1000;
26 uint rec = nSamples;
27 int x, y;
28
29 while(rec--) {
30 input >> x >> y;
31 domain.push_back(x);
32 codomain.push_back(y);
33 }
34
35 return true;
36
37 // the original sample training data
38/* nSamples = 10;
39 int x = 0;
40 for(uint i = 0; i < nSamples; i++) {
41 domain.push_back(x);
42 codomain.push_back(2*x + (int) sqrt(1.*x) + x%3);
43 x += 2;
44 }
45 return true;
46*/
47}
48
49
50FitnessP PrimeEvalOp::evaluate(IndividualP individual)
51{
52 // we try to minimize the function value, so we use FitnessMin fitness (for minimization problems)
53 FitnessP fitness (new FitnessMin);
54
55 // get the genotype we defined in the configuration file
56 Tree::Tree* tree = (Tree::Tree*) individual->getGenotype().get();
57 // (you can also use boost smart pointers:)
58 //TreeP tree = boost::static_pointer_cast<Tree::Tree> (individual->getGenotype());
59
60 double value = 0;
61 for(uint i = 0; i < nSamples; i++) {
62 // for each test data instance, the x value (domain) must be set
63 tree->setTerminalValue("X", &domain[i]);
64 // get the y value of the current tree
65 int result;
66 tree->execute(&result);
67 // interpret result
68 double key = 1;
69 if(abs(result) <= 1)
70 key = 0;
71 // count the errors
72 value += abs(codomain[i] - key);
73 }
74 fitness->setValue(value);
75
76 return fitness;
77}
78
79
80
81
83// integer functions for tree elements
84//
85
86//
87// inherit the Div primitive to define handling integers
88//
89class DivInt : public Tree::Primitives::Div
90{
91public:
92 void execute(void* result, Tree::Tree &tree)
93 {
94 int first, second;
95 int& division = *(int*)result;
96 getNextArgument(&first, tree);
97 getNextArgument(&second, tree);
98
99 // T must be auto castable to double!
100 division = abs(second) > 0.000000001 ? first / second : 1;
101 }
102};
103
104
105//
106// square root function for integers
107//
109{
110public:
111 Sqrt()
112 {
113 nArguments_ = 1;
114 name_ = "sqrt";
115 }
116 void execute(void* result, Tree::Tree& tree)
117 {
118 int& arg = *(int*)result;
119 getNextArgument(&arg, tree);
120
121 if(arg > 0)
122 arg = (int) sqrt(1. * arg);
123 else
124 arg = 0;
125 }
126 ~Sqrt()
127 { }
128};
129
130
131//
132// modulo function for integers
133//
134class Mod : public Tree::Primitives::Primitive
135{
136public:
137 Mod()
138 {
139 nArguments_ = 2;
140 name_ = "%";
141 }
142 void execute(void* result, Tree::Tree& tree)
143 {
144 int first, second;
145 int& modulo = *(int*)result;
146 getNextArgument(&first, tree);
147 getNextArgument(&second, tree);
148
149 modulo = first;
150 if(second != 0)
151 modulo = first % second;
152 }
153 ~Mod()
154 { }
155};
156
157
158
159
160uint showTree(Tree::Tree* tree, uint iNode = 0, uint prefix = 0)
161{
162 Tree::PrimitiveP prim = tree->at(iNode)->primitive_;
163 int arity = prim->getNumberOfArguments();
164
165 if(arity == 0) {
166 cout << prim->getName();
167 }
168 else if(prim->getName() == "pow") {
169 cout << "pow(";
170 iNode++;
171 iNode = showTree(tree, iNode, prefix);
172 cout << ",";
173 iNode++;
174 iNode = showTree(tree, iNode, prefix);
175 cout << ")";
176 }
177 else if(arity == 2) {
178 cout << "(";
179 iNode++;
180 iNode = showTree(tree, iNode, prefix);
181 cout << prim->getName();
182 iNode++;
183 iNode = showTree(tree, iNode, prefix);
184 cout << ")";
185 }
186 else {
187 cout << prim->getName();
188 cout << "(";
189 for(int child = 0; child < arity; child++) {
190 iNode++;
191 iNode = showTree(tree, iNode, prefix);
192 }
193 cout << ")";
194 }
195 return iNode;
196}
197
198
199
200
202// main program
203//
204int main(int argc, char **argv)
205{
206 StateP state (new State);
207
208 // set the evaluation operator
209 state->setEvalOp(new PrimeEvalOp);
210
211 // create tree genotype
212 TreeP tree (new Tree::Tree);
213
214 // create functions for integer variables and add them to function set
215 Tree::PrimitiveP mul (new Tree::Primitives::MulT<int>);
216 tree->addFunction(mul);
217 Tree::PrimitiveP div (new DivInt);
218 tree->addFunction(div);
219 Tree::PrimitiveP add (new Tree::Primitives::AddT<int>);
220 tree->addFunction(add);
221 Tree::PrimitiveP sub (new Tree::Primitives::SubT<int>);
222 tree->addFunction(sub);
223 Tree::PrimitiveP sqrt (new Sqrt);
224 tree->addFunction(sqrt);
225 Tree::PrimitiveP mod (new Mod);
226 tree->addFunction(mod);
227
228 // register genotype with our primitives
229 state->addGenotype(tree);
230
231 state->initialize(argc, argv);
232 state->run();
233
234 Tree::Tree* best = (Tree::Tree*) state->getHoF()->getBest().at(0)->getGenotype().get();
235 showTree(best);
236
237
238 return 0;
239}
Definition: main.cpp:101
void execute(void *result, Tree::Tree &tree)
Execute the primitive.
Definition: main_moj.cpp:92
Evaluation base class.
Definition: EvaluateOp.h:17
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
Definition: main.cpp:146
void execute(void *result, Tree::Tree &tree)
Execute the primitive.
Definition: main_moj.cpp:142
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.
Definition: main.cpp:120
void execute(void *result, Tree::Tree &tree)
Execute the primitive.
Definition: main_moj.cpp:116
State class - backbone of the framework.
Definition: State.h:39
Add function primitive (Tree genotype)
Definition: Add.h:14
Div function primitive (Tree genotype)
Definition: Div.h:17
Mul function primitive (Tree genotype)
Definition: Mul.h:14
Base primitive class (Tree genotype).
Definition: Primitive.h:37
void getNextArgument(void *result, Tree &tree)
Execute next child node's primitive (execute next subtree).
Definition: Primitive.cpp:71
Sub function primitive (Tree genotype)
Definition: Sub.h:14
Tree class - implements genotype as a tree.
Definition: Tree_c.h:29
bool addFunction(PrimitiveP)
Add user defined function primitive. Must be called prior to initialization (no impact otherwise).
Definition: Tree.cpp:80
void setTerminalValue(std::string, void *)
Set a terminal's value.
Definition: Tree.cpp:504
void execute(void *)
Execute current tree.
Definition: Tree.cpp:362