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