ECF 1.5
Cartesian.cpp
1#include <deque>
2#include <ECF_base.h>
3#include "Cartesian.h"
4#include "Cartesian_genotype.h"
5namespace cartesian{
6
7 Cartesian::Cartesian()
8 {
9 name_ = "Cartesian";
10 }
11
12
14 {
15 Cartesian *newObject = new Cartesian(*this);
16
17 return newObject;
18
19 }
20 std::vector<CrossoverOpP> Cartesian::getCrossoverOp()
21 {
22 std::vector<CrossoverOpP> crossoverOperators;
23 crossoverOperators.push_back((CrossoverOpP) (new CartesianCrxUniform));
24 crossoverOperators.push_back((CrossoverOpP) (new CartesianCrxHalfUniform));
25 crossoverOperators.push_back((CrossoverOpP) (new CartesianCrxOnePoint));
26 return crossoverOperators;
27 }
28
29 std::vector<MutationOpP> Cartesian::getMutationOp()
30 {
31 std::vector<MutationOpP> mutationOperators;
32 mutationOperators.push_back((MutationOpP) (new MutateFunction));
33 mutationOperators.push_back((MutationOpP) (new MutateFunctionSilent));
34 mutationOperators.push_back((MutationOpP) (new MutateFunctionSwap));
35 mutationOperators.push_back((MutationOpP) (new MutateConnection));
36 mutationOperators.push_back((MutationOpP) (new MutateConnectionSilent));
37 mutationOperators.push_back((MutationOpP) (new MutateIntoSilent));
38 return mutationOperators;
39 }
40
42 {
43 registerParameter(state, "numoutputs", (voidP) (new uint(1)), ECF::UINT, "number of functional outputs (default: 1)");
44 registerParameter(state, "numrows", (voidP) (new uint(1)), ECF::UINT, "number of rows (default: 1)");
45 registerParameter(state, "numcols", (voidP) (new uint(100)), ECF::UINT, "number of columns (default: 100)");
46 registerParameter(state, "levelsback", (voidP) (new uint(1)), ECF::UINT, "number of previous columns to be used as possible inputs (default: 1)");
47 registerParameter(state, "numvariables", (voidP) (new uint(1)), ECF::UINT, "number of input variables (default: 1)");
48 registerParameter(state, "constantset", (voidP) (new std::string), ECF::STRING, "set of functions to use (default: none)");
49 registerParameter(state, "functionset", (voidP) (new std::string), ECF::STRING, "set of input constants (default: none)");
50 }
51
52
53 bool Cartesian::initialize(StateP state)
54 {
55 state_ = state;
56 std::stringstream ss;
57 std::string names,name;
58 voidP sptr;
59
60 // create and initialize the function set
61 functionSet_ = static_cast<FunctionSetP> (new FunctionSet);
62 functionSet_->initialize(state_);
63
64
65 uint number;
66 //Simple parameters
67 sptr = getParameterValue(state, "numvariables");
68 number = *((uint*) sptr.get());
69 if(number <= 0) {
70 std::cerr << "Genotype initialization error: Number of variables is lesser than 1 or can not be parsed into a number.\n";
71 return false;
72 }
73 nVariables = number;
74
75 sptr = getParameterValue(state,"numoutputs");
76 number = *((uint*) sptr.get());
77 if(number <= 0) {
78 std::cerr << "Genotype initialization error: Number of outputs is lesser than 1 or can not be parsed into a number.\n";
79 return false;
80 }
81 nOutputs = number;
82
83 sptr = getParameterValue(state,"numrows");
84 number = *((uint*) sptr.get());
85 if(number <= 0) {
86 std::cerr << "Genotype initialization error: Number of rows is lesser than 1 or can not be parsed into a number.\n";
87 return false;
88 }
89 nRows = number;
90
91 sptr = getParameterValue(state,"numcols");
92 number = *((uint*) sptr.get());
93 if(number <= 0) {
94 std::cerr << "Genotype initialization error: Number of columns is lesser than 1 or can not be parsed into a number.\n";
95 return false;
96 }
97 nCols = number;
98
99 sptr = getParameterValue(state,"levelsback");
100 number = *((uint*) sptr.get());
101 if(number <= 0) {
102 std::cerr << "Genotype initialization error: Number of columns is lesser than 1 or can not be parsed into a number.\n";
103 return false;
104 }
105 nLevelsBack = number;
106 if(nLevelsBack > nCols) {
108 }
109
110 sptr = getParameterValue(state,"constantset");
111 names = *((std::string*) sptr.get());
112 number = 0;
113 ss.str("");
114 ss.clear();
115 ss << names;
116 while(ss >> name) {
117 ++number;
118 }
119 nConstants = number;
121
122 //Functionset parametri su malo složeniji
123 sptr = getParameterValue(state, "functionset");
124 names = *((std::string*) sptr.get());
125 ss.str("");
126 ss.clear();
127 ss << names;
128 name="";
129
130 while(ss >> name) {
131 functionSet_->addFunction(name);
132 nFunctions++;
133 }
134
135 std::map<std::string, FunctionP_basic>::iterator it;
136 for (it = functionSet_->mActiveFunctions_.begin(); it != functionSet_->mActiveFunctions_.end(); it++) {
137 uint nArgs = it->second->getNumOfArgs();
138 if (nArgs > maxArity)
139 {
140 maxArity = nArgs;
141 }
142 }
144 return true;
145 }
146
147 void Cartesian::read(XMLNode &xCart)
148 {
149 std::string s = xCart.getText(0);
150 std::istringstream ss(s);
151 std::string token;
152 uint i = 0;
153 bool flag = false;
154 uint functionId = 0;
155 std::vector<uint> operands;
156 uint counter = 0;
157 while (getline(ss, token, ' '))
158 {
159 if(!flag) {
160 functionId = str2uint(token);
161 flag = true;
162 counter = functionSet_->vActiveFunctions_[functionId]->getNumOfArgs();
163 }
164 else{
165 operands.push_back(str2uint(token));
166 counter--;
167 if(counter == 0) {
168 flag = false;
169 this->at(i++) = CartesianGene(functionId,operands);
170 }
171 }
172 }
173 for(uint j = this->size() - 1; j > this->size() - 1 - nOutputs; j--) {
174 this->operator[](j).isOutput = true;
175 }
176 }
177
178 void Cartesian::write(XMLNode &xCart)
179 {
180 xCart = XMLNode::createXMLTopNode("Cartesian");
181 std::stringstream sValue;
182 sValue << this->size();
183 xCart.addAttribute("size", sValue.str().c_str());
184
185 sValue.str("");
186
187 // write genome to sValue
188 std::vector<CartesianGene>& genome = *this;
189 for(uint i = 0; i < genome.size(); i++) {
190 sValue << genome[i];
191 }
192 xCart.addText(sValue.str().c_str());
193 }
194
195 uint Cartesian::getGenomeSize()
196 {
197 return this->size();
198 }
199
200 uint Cartesian::getRowNumber(uint index)
201 {
202 return index/nCols;
203 }
204
214 {
215 uint minimum = nInputs + nCols * nLevelsBack;
216
217 //Index of the first element of a row
218 uint firstElementOfARow = nInputs + rowNumber*nCols;
219 if(minimum <= firstElementOfARow) {
220 minimum = firstElementOfARow - nLevelsBack*nCols;
221 }
222 else {
223 minimum = 0;
224 }
225 return state_->getRandomizer()->getRandomInteger(minimum, firstElementOfARow -1);
226 }
227
228 std::set<uint> Cartesian::allPossibleConnection(uint rowNumber)
229 {
230 uint minimum = nInputs + nCols * nLevelsBack;
231 //Index of the first element of a row
232 uint firstElementOfARow = nInputs + rowNumber*nCols;
233 if(minimum <= firstElementOfARow) {
234 minimum = firstElementOfARow - nLevelsBack*nCols;
235 }
236 else {
237 minimum = 0;
238 }
239 std::set<uint> all;
240 for(uint i = minimum; i < firstElementOfARow; i++) {
241 all.insert(i);
242 }
243 return all;
244 }
245
251 std::vector<uint> Cartesian::getActiveTrail(uint output_number)
252 {
253 std::vector<uint> trail;
254 std::deque<uint> working_deque;
255 uint start_index = this->size() - nOutputs + output_number;
256 uint start_value = this->operator[](start_index).value;
257 working_deque.push_back(start_value);
258 while(!working_deque.empty()) {
259 uint working_index = working_deque.front();
260 working_deque.pop_front();
261 if(working_index >= nInputs) {
262 trail.push_back(working_index - nInputs);
263 const CartesianGene& gene = this->at(working_index - nInputs);
264 if(gene.isOutput) {
265 std::cout << "Something went wrong. Trail is considering an output index.\n";
266 }
267 for(uint i = 0; i < gene.inputConnections.size(); i++) {
268 working_deque.push_back(gene.inputConnections[i]);
269 }
270 }
271 }
272 return trail;
273 }
274
275 std::vector<std::vector<uint> > Cartesian::getActiveTrails()
276 {
277 std::vector<std::vector<uint> > allTrails;
278 for(uint i = 0; i < nOutputs; i++) {
279 allTrails.push_back(getActiveTrail(i));
280 }
281 return allTrails;
282 }
283
285 {
286 const std::vector<FunctionP_basic>& vRef = functionSet_->vActiveFunctions_;
287 for(uint i = 0; i < nRows; i++) {
288 for(uint j = 0; j < nCols; j++) {
289 uint functionID = get_random_int(0, functionSet_->vActiveFunctions_.size() - 1);
290 uint noOfOperands = vRef[functionID]->getNumOfArgs();
291 std::vector<uint> connections;
292 for(uint k = 0; k < noOfOperands; k++) {
293 connections.push_back(randomConnectionGenerator(i));
294 }
295 this->push_back(CartesianGene(functionID,connections));
296 }
297 }
298 for(uint i = 0; i < nOutputs; i++) {
299 this->push_back(CartesianGene(randomConnectionGenerator(nRows),std::vector<uint>(),true));
300 }
301 }
302
303
304 int Cartesian::get_random_int(int from, int to) {
305 return this->state_->getRandomizer()->getRandomInteger(from,to);
306 }
307
308
309 double Cartesian::get_random_double(int from, int to) {
310 return rand() % (to - from + 1) + from;
311 }
312
313 void Cartesian::evaluate(const std::vector<double> &inputData, std::vector<double> &results)
314 {
315 std::vector<double> working_vector(inputData);
316 std::vector<double> operands;
317 const std::vector<FunctionP_basic>& vRef = functionSet_->vActiveFunctions_;
318 double result = 0;
319
320 for(uint i = 0; i < this->size() - nOutputs; i++) {
321 const CartesianGene& gene = this->operator[](i);
322 for(uint j = 0; j < gene.inputConnections.size(); j++) {
323 operands.push_back(working_vector[gene.inputConnections[j]]);
324 }
325 vRef[gene.value]->evaluate(operands,result);
326 working_vector.push_back(result);
327 operands.clear();
328 result = 0;
329 }
330 for(uint i = this->size() - nOutputs; i < this->size(); i++) {
331 results.push_back(working_vector[this->operator[](i).value]);
332 }
333 }
334
335 double Cartesian::static_random_double(int from, int to) {
336 return rand() % (to - from + 1) + from;
337 }
338}
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 * copy()
Definition: Cartesian.cpp:13
uint nInputs
total number of inputs (including constants)
uint randomConnectionGenerator(uint rowNumber)
Definition: Cartesian.cpp:213
uint nVariables
number of input variables
void write(XMLNode &xCart)
Definition: Cartesian.cpp:178
void evaluate(const vector< double > &inputData, vector< double > &results)
vector< MutationOpP > getMutationOp()
Definition: Cartesian.cpp:29
std::vector< uint > getActiveTrail(uint output_number)
Definition: Cartesian.cpp:251
void read(XMLNode &xCart)
Definition: Cartesian.cpp:147
vector< CrossoverOpP > getCrossoverOp()
Definition: Cartesian.cpp:20
uint nLevelsBack
levels back parameter
uint nRows
number of rows
uint maxArity
max number of inputs for all function nodes (gates)
bool initialize(StateP state)
Definition: Cartesian.cpp:53
uint nOutputs
number of final outputs
uint nCols
number of columns
StateP state_
local copy of state
std::vector< std::vector< uint > > getActiveTrails()
Definition: Cartesian.cpp:275
uint nFunctions
number of functions
uint nConstants
number of input constants
void registerParameters(StateP state)
Definition: Cartesian.cpp:41