ECF 1.5
Cartesian.cpp
1#include "Cartesian.h"
2#include <cctype>
3#include <map>
4#include <vector>
5
6namespace cart {
7
8Cartesian::Cartesian(void)
9{
10 name_ = "Cartesian";
11}
12
13Cartesian::~Cartesian(void)
14{
15}
16
17bool Cartesian::initialize(StateP state)
18{
19 state_ = state;
20
21 stringstream names;
22 string name;
23 voidP sptr;
24
25 sptr = getParameterValue(state, "type");
26 names << *((string*) sptr.get());
27 name = names.str();
28
29 //type defines data type (from domain and codomain), if not defined default is double
30 if (name.length() == 0)
31 {
32 name = "double";
33 }
34 else if (name != "double" && name != "int" && name != "uint")
35 {
36 cerr << "Genoype initialization error:: Has to be one of types: double, int, uint" << endl;
37 return false;
38 }
39 else
40 { }
41
42 //function nodes must be able to work with defined data type
43 funcSet = static_cast<FunctionSetP> (new FunctionSet(name));
44
45 sptr = getParameterValue(state, "numinputconns");
46 name = *((string*) sptr.get());
47 if (name.length() == 0)
48 {
49 cerr << "Genotype initialization error:: Number of input connections is undefined." << endl;
50 return false;
51 }
52 inputConns = str2uint(name);
53 if (inputConns == 0)
54 {
55 cerr << "Genotype initialization error:: Number of input connections can't be zero." << endl;
56 return false;
57 }
58
59 vector<string> functionset;
60 sptr = getParameterValue(state, "functionset");
61 //one function can be defined with multiple (but different) number of arguments
62 uint arg;
63 map<std::string, std::vector<uint> > args;
64
65 //extract function names and number of their arguments, if number of arguments isn't defined, then
66 //it's default (some function nodes can't have variable number of arguments, e.g. sin or cos)
67 names.str("");
68 names.clear();
69 names << *((string*) sptr.get());
70 while (names >> name)
71 {
72 //if it isn't function name then it can be number of arguments for the last read function name
73 if (!funcSet->existFunc[name])
74 {
75 char *c = (char *)name.c_str();
76 for (int i = 0; i < (int)name.length(); i++)
77 {
78 if (!isdigit(c[i]))
79 {
80 cerr << "Genoype initialization error:: Function " << name << " isn't implemented." << endl;
81 return false;
82 }
83 }
84 //some functions may go with many number of arguments, all numbers of arguments must be defined
85 //after stating the name of that function (in configuration file)
86 if (args[functionset.back()].empty())
87 {
88 vector<uint> vec;
89 vec.push_back(str2uint(name));
90 args[functionset.back()] = vec;
91 }
92 else
93 {
94 arg = str2uint(name);
95 //there can't be defined two or more functions with the same name and the same number
96 //of arguments
97 for (int i = 0; i < args[functionset.back()].size(); i++)
98 {
99 if (arg == args[functionset.back()].at(i))
100 {
101 cerr << "Genotype initialization error:: Number of arguments " << arg;
102 cerr << " for function " << functionset.back() << " already taken." << endl;
103 return false;
104 }
105 }
106 args[functionset.back()].push_back(arg);
107 }
108 }
109 else
110 {
111 functionset.push_back(name);
112 }
113 }
114
115 if (functionset.size() == 0)
116 {
117 cerr << "Genotype initialization error:: Must be defined at least one function in function set." << endl;
118 return false;
119 }
120
121 //create function objects
122 for (int i = 0; i < (int)functionset.size(); i++)
123 {
124 if (!args[functionset.at(i)].empty())
125 {
126 for (int j = 0; j < args[functionset.at(i)].size(); j++)
127 {
128 if (args[functionset.at(i)].at(j) > inputConns)
129 {
130 cerr << "Genoype initialization error:: Number of arguments for " << functionset.at(i);
131 cerr << " greater than number of input connections." << endl;
132 return false;
133 }
134 if (!funcSet->addFunction(functionset.at(i), args[functionset.at(i)].at(j)))
135 {
136 return false;
137 }
138 }
139 }
140 else
141 {
142 if (!funcSet->addFunction(functionset.at(i)))
143 {
144 return false;
145 }
146 }
147 }
148
149 //number of possible functions
150 numFunc = (uint)funcSet->size();
151
152 //extract constants, constants aren't necessary
153 sptr = getParameterValue(state, "constantset");
154 constantset = sptr;
155 names.str("");
156 names.clear();
157 names << *((string*) sptr.get());
158 uint numCons = 0;
159 while (names >> name)
160 {
161 ++numCons;
162 }
163
164 //num of variables = num of inputs to be replaced by elements from domain
165 sptr = getParameterValue(state, "numvariables");
166 name = *((string*) sptr.get());
167 numVars = str2uint(name);
168
169 inputs = numVars + numCons;
170 if (inputs == 0)
171 {
172 cerr << "Genotype initialization error:: Number of inputs can't be zero." << endl;
173 return false;
174 }
175
176 sptr = getParameterValue(state, "numoutputs");
177 name = *((string*) sptr.get());
178 if (name.length() == 0)
179 {
180 cerr << "Genotype initialization error:: Number of outputs is undefined." << endl;
181 return false;
182 }
183 outputs = str2uint(name);
184 if (outputs == 0)
185 {
186 cerr << "Genotype initialization error:: Number of outputs can't be zero." << endl;
187 return false;
188 }
189
190 sptr = getParameterValue(state, "numrows");
191 name = *((string*) sptr.get());
192 if (name.length() == 0)
193 {
194 cerr << "Genotype initialization error:: Number of rows is undefined." << endl;
195 return false;
196 }
197 rows = str2uint(name);
198 if (rows == 0)
199 {
200 cerr << "Genotype initialization error:: Number of rows can't be zero." << endl;
201 return false;
202 }
203
204 sptr = getParameterValue(state, "numcols");
205 name = *((string*) sptr.get());
206 if (name.length() == 0)
207 {
208 cerr << "Genotype initialization error:: Number of columns is undefined." << endl;
209 return false;
210 }
211 cols = str2uint(name);
212 if (cols == 0)
213 {
214 cerr << "Genotype initialization error:: Number of columns can't be zero." << endl;
215 return false;
216 }
217
218
219 sptr = getParameterValue(state, "levelsback");
220 name = *((string*) sptr.get());
221 //if not defined, default is 1
222 if (name.length() == 0)
223 {
224 levelsBack = 1;
225 }
226 else
227 {
228 levelsBack = str2uint(name);
229 }
230
231 makeGenotype();
232
233 //printGenotype();
234
235 return true;
236}
237
239{
240 Cartesian *newObject = new Cartesian(*this);
241
242 //create new copy of existing genotype
243 for(int i = 0; i < (int) this->size(); i++) {
244 (*newObject)[i] = this->at(i);
245 }
246 return newObject;
247}
248
249vector<CrossoverOpP> Cartesian::getCrossoverOp()
250{
251 vector<CrossoverOpP> crossops;
252 crossops.push_back((CrossoverOpP) (new CartesianCrsOnePoint));
253 return crossops;
254}
255
256vector<MutationOpP> Cartesian::getMutationOp()
257{
258 vector<MutationOpP> mutops;
259 mutops.push_back((MutationOpP) (new CartesianMutOnePoint));
260 return mutops;
261}
262
264{
265 registerParameter(state, "type", (voidP) (new string), ECF::STRING);
266 registerParameter(state, "numoutputs", (voidP) (new string), ECF::STRING);
267 registerParameter(state, "numinputconns", (voidP) (new string), ECF::STRING);
268 registerParameter(state, "numrows", (voidP) (new string), ECF::STRING);
269 registerParameter(state, "numcols", (voidP) (new string), ECF::STRING);
270 registerParameter(state, "levelsback", (voidP) (new string), ECF::STRING);
271 // variableset + constantset = terminalset
272 registerParameter(state, "numvariables", (voidP) (new string), ECF::STRING);
273 registerParameter(state, "constantset", (voidP) (new string), ECF::STRING);
274 registerParameter(state, "functionset", (voidP) (new string), ECF::STRING);
275}
276
277void Cartesian::read(XMLNode &xCart)
278{
279}
280
281void Cartesian::write(XMLNode &xCart)
282{
283 xCart = XMLNode::createXMLTopNode("Cartesian");
284 stringstream sValue;
285 sValue << this->size();
286 xCart.addAttribute("size", sValue.str().c_str());
287
288 sValue.str("");
289 for (int i = 0; i < (int)(rows * cols * (inputConns + 1)); i++)
290 {
291 sValue << this->at(i) << " ";
292 if (((i + 1) % (inputConns + 1)) == 0)
293 {
294 sValue << " ";
295 }
296 }
297 for (int i = 0; i < (int)outputs; i++)
298 {
299 sValue << this->at((rows * cols * (inputConns + 1)) + i) << " ";
300 }
301
302 xCart.addText(sValue.str().c_str());
303}
304
305uint Cartesian::getGenomeSize()
306{
307 return 0;
308}
309
311{
312 uint currCol = 0;
313 //generate nodes - input connections + one function
314 for (int i = 0; i < (int)(rows * cols); i++)
315 {
316 if ((i % rows) == 0 && i != 0)
317 {
318 ++currCol;
319 }
320 for (int j = 0; j < (int)inputConns; j++)
321 {
322 this->push_back(randInputConn(currCol));
323 }
324 this->push_back(randFunction());
325 }
326 //generate outputs
327 for (int i = 0; i < (int)outputs; i++)
328 {
329 this->push_back(randOutput());
330 }
331}
332
333uint Cartesian::randInputConn(uint currCol)
334{
335 int emax = inputs + (currCol * rows);
336
337 if (currCol < levelsBack)
338 {
339 return (uint)(state_->getRandomizer()->getRandomInteger(0, emax - 1));
340 }
341
342 int emin = inputs + ((currCol - levelsBack) * rows);
343 return (uint)(state_->getRandomizer()->getRandomInteger(emin, emax - 1));
344}
345
347{
348 int hmin = inputs + ((cols - levelsBack) * rows);
349 int hmax = inputs + (cols * rows);
350 return (uint)(state_->getRandomizer()->getRandomInteger(hmin, hmax - 1));
351}
352
354{
355 return (uint)(state_->getRandomizer()->getRandomInteger(0, numFunc - 1));
356}
357
358void Cartesian::evaluate(voidP inputs, void* result, uint funcNum)
359{
360 funcSet->evaluate(inputs, result, funcNum);
361}
362
364{
365 for (int i = 0; i < (int)(rows * cols * (inputConns + 1)); i++)
366 {
367 cout << this->at(i) << " ";
368 if (((i + 1) % (inputConns + 1)) == 0)
369 {
370 cout << " ";
371 }
372 }
373 for (int i = 0; i < (int)outputs; i++)
374 {
375 cout << this->at((rows * cols * (inputConns + 1)) + i) << " ";
376 }
377 cout << endl;
378}
379
381{
382 return inputs;
383}
384
386{
387 return outputs;
388}
389
391{
392 return inputConns;
393}
394
396{
397 return constantset;
398}
399
401{
402 return rows;
403}
404
406{
407 return cols;
408}
409
411{
412 return levelsBack;
413}
414
416{
417 return numVars;
418}
419
420}
421
422
423
424
425
voidP getParameterValue(StateP state, std::string name)
Read single parameter value from Registry.
Definition: Genotype.cpp:10
bool registerParameter(StateP state, std::string name, voidP value, enum ECF::type T, std::string description="")
Register a single parameter.
Definition: Genotype.cpp:4
std::string name_
genotype's name
Definition: Genotype.h:109
Cartesian genotype: one point crossover operator.
uint numVars
number of variables
Definition: Cartesian_c.h:127
void registerParameters(StateP state)
Definition: Cartesian.cpp:263
Cartesian * copy()
Definition: Cartesian.cpp:238
voidP constantset
all possible constants
Definition: Cartesian_c.h:129
uint getNumOfRows()
Definition: Cartesian.cpp:400
vector< MutationOpP > getMutationOp()
Definition: Cartesian.cpp:256
voidP getConstantNames()
Definition: Cartesian.cpp:395
uint cols
number of columns
Definition: Cartesian_c.h:125
uint getLevelsBack()
Definition: Cartesian.cpp:410
uint levelsBack
levels back parameter
Definition: Cartesian_c.h:126
void write(XMLNode &xCart)
Definition: Cartesian.cpp:281
uint getNumOfOutputs()
Definition: Cartesian.cpp:385
uint numFunc
number of functions
Definition: Cartesian_c.h:128
uint randInputConn(uint currCol)
Definition: Cartesian.cpp:333
StateP state_
local copy of state
Definition: Cartesian_c.h:119
void makeGenotype()
Definition: Cartesian.cpp:310
bool initialize(StateP state)
Definition: Cartesian.cpp:17
uint randFunction()
Definition: Cartesian.cpp:353
uint getNumOfInputConn()
Definition: Cartesian.cpp:390
void read(XMLNode &xCart)
Definition: Cartesian.cpp:277
void printGenotype()
Definition: Cartesian.cpp:363
uint inputConns
number of input connections
Definition: Cartesian_c.h:123
uint rows
number of rows
Definition: Cartesian_c.h:124
uint inputs
number of primary inputs
Definition: Cartesian_c.h:121
void evaluate(voidP inputs, void *result, uint funcNum)
Definition: Cartesian.cpp:358
vector< CrossoverOpP > getCrossoverOp()
Definition: Cartesian.cpp:249
uint getNumOfInputs()
Definition: Cartesian.cpp:380
uint outputs
number of final outputs
Definition: Cartesian_c.h:122
uint getNumOfCols()
Definition: Cartesian.cpp:405
FunctionSetP funcSet
function nodes
Definition: Cartesian_c.h:116
Cartesian genotype: one point mutation operator.