00001 #include "Cartesian.h"
00002 #include <cctype>
00003 #include <map>
00004 #include <vector>
00005
00006 namespace cart {
00007
00008 Cartesian::Cartesian(void)
00009 {
00010 name_ = "Cartesian";
00011 }
00012
00013 Cartesian::~Cartesian(void)
00014 {
00015 }
00016
00017 bool Cartesian::initialize(StateP state)
00018 {
00019 state_ = state;
00020
00021 stringstream names;
00022 string name;
00023 voidP sptr;
00024
00025 sptr = getParameterValue(state, "type");
00026 names << *((string*) sptr.get());
00027 name = names.str();
00028
00029
00030 if (name.length() == 0)
00031 {
00032 name = "double";
00033 }
00034 else if (name != "double" && name != "int" && name != "uint")
00035 {
00036 cerr << "Genoype initialization error:: Has to be one of types: double, int, uint" << endl;
00037 return false;
00038 }
00039 else
00040 { }
00041
00042
00043 funcSet = static_cast<FunctionSetP> (new FunctionSet(name));
00044
00045 sptr = getParameterValue(state, "numinputconns");
00046 name = *((string*) sptr.get());
00047 if (name.length() == 0)
00048 {
00049 cerr << "Genotype initialization error:: Number of input connections is undefined." << endl;
00050 return false;
00051 }
00052 inputConns = str2uint(name);
00053 if (inputConns == 0)
00054 {
00055 cerr << "Genotype initialization error:: Number of input connections can't be zero." << endl;
00056 return false;
00057 }
00058
00059 vector<string> functionset;
00060 sptr = getParameterValue(state, "functionset");
00061
00062 uint arg;
00063 map<std::string, std::vector<uint> > args;
00064
00065
00066
00067 names.str("");
00068 names.clear();
00069 names << *((string*) sptr.get());
00070 while (names >> name)
00071 {
00072
00073 if (!funcSet->existFunc[name])
00074 {
00075 char *c = (char *)name.c_str();
00076 for (int i = 0; i < (int)name.length(); i++)
00077 {
00078 if (!isdigit(c[i]))
00079 {
00080 cerr << "Genoype initialization error:: Function " << name << " isn't implemented." << endl;
00081 return false;
00082 }
00083 }
00084
00085
00086 if (args[functionset.back()].empty())
00087 {
00088 vector<uint> vec;
00089 vec.push_back(str2uint(name));
00090 args[functionset.back()] = vec;
00091 }
00092 else
00093 {
00094 arg = str2uint(name);
00095
00096
00097 for (int i = 0; i < args[functionset.back()].size(); i++)
00098 {
00099 if (arg == args[functionset.back()].at(i))
00100 {
00101 cerr << "Genotype initialization error:: Number of arguments " << arg;
00102 cerr << " for function " << functionset.back() << " already taken." << endl;
00103 return false;
00104 }
00105 }
00106 args[functionset.back()].push_back(arg);
00107 }
00108 }
00109 else
00110 {
00111 functionset.push_back(name);
00112 }
00113 }
00114
00115 if (functionset.size() == 0)
00116 {
00117 cerr << "Genotype initialization error:: Must be defined at least one function in function set." << endl;
00118 return false;
00119 }
00120
00121
00122 for (int i = 0; i < (int)functionset.size(); i++)
00123 {
00124 if (!args[functionset.at(i)].empty())
00125 {
00126 for (int j = 0; j < args[functionset.at(i)].size(); j++)
00127 {
00128 if (args[functionset.at(i)].at(j) > inputConns)
00129 {
00130 cerr << "Genoype initialization error:: Number of arguments for " << functionset.at(i);
00131 cerr << " greater than number of input connections." << endl;
00132 return false;
00133 }
00134 if (!funcSet->addFunction(functionset.at(i), args[functionset.at(i)].at(j)))
00135 {
00136 return false;
00137 }
00138 }
00139 }
00140 else
00141 {
00142 if (!funcSet->addFunction(functionset.at(i)))
00143 {
00144 return false;
00145 }
00146 }
00147 }
00148
00149
00150 numFunc = (uint)funcSet->size();
00151
00152
00153 sptr = getParameterValue(state, "constantset");
00154 constantset = sptr;
00155 names.str("");
00156 names.clear();
00157 names << *((string*) sptr.get());
00158 uint numCons = 0;
00159 while (names >> name)
00160 {
00161 ++numCons;
00162 }
00163
00164
00165 sptr = getParameterValue(state, "numvariables");
00166 name = *((string*) sptr.get());
00167 numVars = str2uint(name);
00168
00169 inputs = numVars + numCons;
00170 if (inputs == 0)
00171 {
00172 cerr << "Genotype initialization error:: Number of inputs can't be zero." << endl;
00173 return false;
00174 }
00175
00176 sptr = getParameterValue(state, "numoutputs");
00177 name = *((string*) sptr.get());
00178 if (name.length() == 0)
00179 {
00180 cerr << "Genotype initialization error:: Number of outputs is undefined." << endl;
00181 return false;
00182 }
00183 outputs = str2uint(name);
00184 if (outputs == 0)
00185 {
00186 cerr << "Genotype initialization error:: Number of outputs can't be zero." << endl;
00187 return false;
00188 }
00189
00190 sptr = getParameterValue(state, "numrows");
00191 name = *((string*) sptr.get());
00192 if (name.length() == 0)
00193 {
00194 cerr << "Genotype initialization error:: Number of rows is undefined." << endl;
00195 return false;
00196 }
00197 rows = str2uint(name);
00198 if (rows == 0)
00199 {
00200 cerr << "Genotype initialization error:: Number of rows can't be zero." << endl;
00201 return false;
00202 }
00203
00204 sptr = getParameterValue(state, "numcols");
00205 name = *((string*) sptr.get());
00206 if (name.length() == 0)
00207 {
00208 cerr << "Genotype initialization error:: Number of columns is undefined." << endl;
00209 return false;
00210 }
00211 cols = str2uint(name);
00212 if (cols == 0)
00213 {
00214 cerr << "Genotype initialization error:: Number of columns can't be zero." << endl;
00215 return false;
00216 }
00217
00218
00219 sptr = getParameterValue(state, "levelsback");
00220 name = *((string*) sptr.get());
00221
00222 if (name.length() == 0)
00223 {
00224 levelsBack = 1;
00225 }
00226 else
00227 {
00228 levelsBack = str2uint(name);
00229 }
00230
00231 makeGenotype();
00232
00233
00234
00235 return true;
00236 }
00237
00238 Cartesian* Cartesian::copy()
00239 {
00240 Cartesian *newObject = new Cartesian(*this);
00241
00242
00243 for(int i = 0; i < (int) this->size(); i++) {
00244 (*newObject)[i] = this->at(i);
00245 }
00246 return newObject;
00247 }
00248
00249 vector<CrossoverOpP> Cartesian::getCrossoverOp()
00250 {
00251 vector<CrossoverOpP> crossops;
00252 crossops.push_back((CrossoverOpP) (new CartesianCrsOnePoint));
00253 return crossops;
00254 }
00255
00256 vector<MutationOpP> Cartesian::getMutationOp()
00257 {
00258 vector<MutationOpP> mutops;
00259 mutops.push_back((MutationOpP) (new CartesianMutOnePoint));
00260 return mutops;
00261 }
00262
00263 void Cartesian::registerParameters(StateP state)
00264 {
00265 registerParameter(state, "type", (voidP) (new string), ECF::STRING);
00266 registerParameter(state, "numoutputs", (voidP) (new string), ECF::STRING);
00267 registerParameter(state, "numinputconns", (voidP) (new string), ECF::STRING);
00268 registerParameter(state, "numrows", (voidP) (new string), ECF::STRING);
00269 registerParameter(state, "numcols", (voidP) (new string), ECF::STRING);
00270 registerParameter(state, "levelsback", (voidP) (new string), ECF::STRING);
00271
00272 registerParameter(state, "numvariables", (voidP) (new string), ECF::STRING);
00273 registerParameter(state, "constantset", (voidP) (new string), ECF::STRING);
00274 registerParameter(state, "functionset", (voidP) (new string), ECF::STRING);
00275 }
00276
00277 void Cartesian::read(XMLNode &xCart)
00278 {
00279 }
00280
00281 void Cartesian::write(XMLNode &xCart)
00282 {
00283 xCart = XMLNode::createXMLTopNode("Cartesian");
00284 stringstream sValue;
00285 sValue << this->size();
00286 xCart.addAttribute("size", sValue.str().c_str());
00287
00288 sValue.str("");
00289 for (int i = 0; i < (int)(rows * cols * (inputConns + 1)); i++)
00290 {
00291 sValue << this->at(i) << " ";
00292 if (((i + 1) % (inputConns + 1)) == 0)
00293 {
00294 sValue << " ";
00295 }
00296 }
00297 for (int i = 0; i < (int)outputs; i++)
00298 {
00299 sValue << this->at((rows * cols * (inputConns + 1)) + i) << " ";
00300 }
00301
00302 xCart.addText(sValue.str().c_str());
00303 }
00304
00305 uint Cartesian::getGenomeSize()
00306 {
00307 return 0;
00308 }
00309
00310 void Cartesian::makeGenotype()
00311 {
00312 uint currCol = 0;
00313
00314 for (int i = 0; i < (int)(rows * cols); i++)
00315 {
00316 if ((i % rows) == 0 && i != 0)
00317 {
00318 ++currCol;
00319 }
00320 for (int j = 0; j < (int)inputConns; j++)
00321 {
00322 this->push_back(randInputConn(currCol));
00323 }
00324 this->push_back(randFunction());
00325 }
00326
00327 for (int i = 0; i < (int)outputs; i++)
00328 {
00329 this->push_back(randOutput());
00330 }
00331 }
00332
00333 uint Cartesian::randInputConn(uint currCol)
00334 {
00335 int emax = inputs + (currCol * rows);
00336
00337 if (currCol < levelsBack)
00338 {
00339 return (uint)(state_->getRandomizer()->getRandomInteger(0, emax - 1));
00340 }
00341
00342 int emin = inputs + ((currCol - levelsBack) * rows);
00343 return (uint)(state_->getRandomizer()->getRandomInteger(emin, emax - 1));
00344 }
00345
00346 uint Cartesian::randOutput()
00347 {
00348 int hmin = inputs + ((cols - levelsBack) * rows);
00349 int hmax = inputs + (cols * rows);
00350 return (uint)(state_->getRandomizer()->getRandomInteger(hmin, hmax - 1));
00351 }
00352
00353 uint Cartesian::randFunction()
00354 {
00355 return (uint)(state_->getRandomizer()->getRandomInteger(0, numFunc - 1));
00356 }
00357
00358 void Cartesian::evaluate(voidP inputs, void* result, uint funcNum)
00359 {
00360 funcSet->evaluate(inputs, result, funcNum);
00361 }
00362
00363 void Cartesian::printGenotype()
00364 {
00365 for (int i = 0; i < (int)(rows * cols * (inputConns + 1)); i++)
00366 {
00367 cout << this->at(i) << " ";
00368 if (((i + 1) % (inputConns + 1)) == 0)
00369 {
00370 cout << " ";
00371 }
00372 }
00373 for (int i = 0; i < (int)outputs; i++)
00374 {
00375 cout << this->at((rows * cols * (inputConns + 1)) + i) << " ";
00376 }
00377 cout << endl;
00378 }
00379
00380 uint Cartesian::getNumOfInputs()
00381 {
00382 return inputs;
00383 }
00384
00385 uint Cartesian::getNumOfOutputs()
00386 {
00387 return outputs;
00388 }
00389
00390 uint Cartesian::getNumOfInputConn()
00391 {
00392 return inputConns;
00393 }
00394
00395 voidP Cartesian::getConstantNames()
00396 {
00397 return constantset;
00398 }
00399
00400 uint Cartesian::getNumOfRows()
00401 {
00402 return rows;
00403 }
00404
00405 uint Cartesian::getNumOfCols()
00406 {
00407 return cols;
00408 }
00409
00410 uint Cartesian::getLevelsBack()
00411 {
00412 return levelsBack;
00413 }
00414
00415 uint Cartesian::getNumVars()
00416 {
00417 return numVars;
00418 }
00419
00420 }
00421
00422
00423
00424
00425