ECF 1.5
main.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<long int> domain;
14 std::vector<long 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 //nSamples = 1928614;
27 uint rec = nSamples;
28 long int x, y;
29
30 while(rec--) {
31 input >> x >> y;
32 domain.push_back(x);
33 codomain.push_back(y);
34 }
35
36 return true;
37
38 // the original sample training data
39/* nSamples = 10;
40 int x = 0;
41 for(uint i = 0; i < nSamples; i++) {
42 domain.push_back(x);
43 codomain.push_back(2*x + (int) sqrt(1.*x) + x%3);
44 x += 2;
45 }
46 return true;
47*/
48}
49
50
51FitnessP PrimeEvalOp::evaluate(IndividualP individual)
52{
53 // we try to minimize the function value, so we use FitnessMin fitness (for minimization problems)
54 FitnessP fitness (new FitnessMin);
55
56 // get the genotype we defined in the configuration file
57 Tree::Tree* tree = (Tree::Tree*) individual->getGenotype().get();
58 // (you can also use boost smart pointers:)
59 //TreeP tree = boost::static_pointer_cast<Tree::Tree> (individual->getGenotype());
60
61 double value = 0;
62 for(uint i = 0; i < nSamples; i++) {
63 // for each test data instance, the x value (domain) must be set
64 tree->setTerminalValue("X", &domain[i]);
65 // get the y value of the current tree
66 long int result;
67 tree->execute(&result);
68 // interpret result
69 double key = 1;
70 if(abs(result) <= 1)
71 key = 0;
72 // count the errors
73 value += abs(codomain[i] - key);
74
75 /*if(codomain[i] == 0 && key == 1)
76 {
77 value += 1;
78 }
79 else if(codomain[i] == 1 && key == 0)
80 {
81 value += 1928614;
82 }*/
83
84 }
85 fitness->setValue(value);
86
87 return fitness;
88}
89
90
91
92
94// integer functions for tree elements
95//
96
97//
98// inherit the Div primitive to define handling integers
99//
101{
102public:
103 void execute(void* result, Tree::Tree &tree)
104 {
105 long int first, second;
106 long int& division = *(long int*)result;
107 getNextArgument(&first, tree);
108 getNextArgument(&second, tree);
109
110 // T must be auto castable to double!
111 division = abs(second) > 0.000000001 ? first / second : 1;
112 }
113};
114
115
116//
117// square root function for integers
118//
120{
121public:
122 Sqrt()
123 {
124 nArguments_ = 1;
125 name_ = "sqrt";
126 }
127 void execute(void* result, Tree::Tree& tree)
128 {
129 long int& arg = *(long int*)result;
130 getNextArgument(&arg, tree);
131
132 if(arg > 0)
133 arg = (long int) sqrt(1. * arg);
134 else
135 arg = 0;
136 }
137 ~Sqrt()
138 { }
139};
140
141
142//
143// modulo function for integers
144//
146{
147public:
148 Mod()
149 {
150 nArguments_ = 2;
151 name_ = "%";
152 }
153 void execute(void* result, Tree::Tree& tree)
154 {
155 long int first, second;
156 long int& modulo = *(long int*)result;
157 getNextArgument(&first, tree);
158 getNextArgument(&second, tree);
159
160 modulo = first;
161 if(second != 0)
162 modulo = first % second;
163 }
164 ~Mod()
165 { }
166};
167
168
169uint showTree(Tree::Tree* tree, uint iNode = 0, uint prefix = 0)
170{
171 Tree::PrimitiveP prim = tree->at(iNode)->primitive_;
172 int arity = prim->getNumberOfArguments();
173
174 if(arity == 0) {
175 cout << prim->getName();
176 }
177 else if(prim->getName() == "pow") {
178 cout << "pow(";
179 iNode++;
180 iNode = showTree(tree, iNode, prefix);
181 cout << ",";
182 iNode++;
183 iNode = showTree(tree, iNode, prefix);
184 cout << ")";
185 }
186 else if(arity == 2) {
187 cout << "(";
188 iNode++;
189 iNode = showTree(tree, iNode, prefix);
190 cout << prim->getName();
191 iNode++;
192 iNode = showTree(tree, iNode, prefix);
193 cout << ")";
194 }
195 else {
196 cout << prim->getName();
197 cout << "(";
198 for(int child = 0; child < arity; child++) {
199 iNode++;
200 iNode = showTree(tree, iNode, prefix);
201 }
202 cout << ")";
203 }
204 return iNode;
205}
206
207
208
209int isPrime6k1_sp(unsigned long long int number)
210{
211 if (number == 0)
212 {
213 return 0;
214 }
215 else if (number == 1)
216 {
217 return 0;
218 }
219 else if (number < 4)
220 {
221 return 1;
222 }
223 else if (number % 2 == 0)
224 {
225 return 0;
226 }
227 else if (number < 9)
228 {
229 return true;
230 }
231 else if (number%3==0)
232 {
233 return 0;
234 }
235 else
236 {
237 unsigned long long int up_range;
238 up_range = (unsigned long long int) sqrt(1. * number);
239
240 unsigned long long int tmp = 5;
241
242 while (tmp<=up_range)
243 {
244 if (number%tmp==0)
245 {
246 return 0;
247 }
248 if (number%(tmp+2)==0)
249 {
250 return 0;
251 }
252
253 tmp = tmp + 6;
254 }
255
256 return 1;
257 }
258}
259
260
262// main program
263//
264int main(int argc, char **argv)
265{
266 StateP state (new State);
267
268 // set the evaluation operator
269 state->setEvalOp(new PrimeEvalOp);
270
271 // create tree genotype
272 TreeP tree (new Tree::Tree);
273
274 // create functions for integer variables and add them to function set
275 Tree::PrimitiveP mul (new Tree::Primitives::MulT<long int>);
276 tree->addFunction(mul);
277 Tree::PrimitiveP div (new DivInt);
278 tree->addFunction(div);
279 Tree::PrimitiveP add (new Tree::Primitives::AddT<long int>);
280 tree->addFunction(add);
281 Tree::PrimitiveP sub (new Tree::Primitives::SubT<long int>);
282 tree->addFunction(sub);
283 Tree::PrimitiveP sqrt (new Sqrt);
284 tree->addFunction(sqrt);
285 Tree::PrimitiveP mod (new Mod);
286 tree->addFunction(mod);
287
288 // register genotype with our primitives
289 state->addGenotype(tree);
290
291 state->initialize(argc, argv);
292 state->run();
293
294 Tree::Tree* best = (Tree::Tree*) state->getHoF()->getBest().at(0)->getGenotype().get();
295
296
297 printf("\n\n");
298 showTree(best);
299 printf("\n\n");
300
301
302 long int i;
303 for(i=32582658; i < 260000000; i++)
304 {
305 if( isPrime6k1_sp(i) == 1 )
306 {
307 if( !(isPrime6k1_sp(2*i+1) == 1 && i % 4 == 3) )
308 {
309 best->setTerminalValue("X", &i);
310 // get the y value of the current tree
311 long int result;
312 best->execute(&result);
313 // interpret result
314 double key = 1;
315 if(abs(result) <= 1)
316 key = 0;
317 // count the errors
318 if( key == 1)
319 {
320 printf("%ld\n", i);
321 }
322 }
323 }
324
325 if(i % 100000 == 0)
326 cout << ".";
327
328 }
329
330
331 return 0;
332}
Definition: main.cpp:101
void execute(void *result, Tree::Tree &tree)
Execute the primitive.
Definition: main.cpp:103
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.cpp:153
FitnessP evaluate(IndividualP individual)
Evaluate a single individual. Method must create and return a Fitness object.
Definition: main.cpp:51
bool initialize(StateP)
Initialize the evaluator. Called before first evaluation occurs.
Definition: main.cpp:20
Definition: main.cpp:120
void execute(void *result, Tree::Tree &tree)
Execute the primitive.
Definition: main.cpp:127
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