• Main Page
  • Modules
  • Classes
  • Files
  • File List

D:/Projekt/ECF_trunk/ECF/cartesian/Cartesian.cpp

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     //type defines data type (from domain and codomain), if not defined default is double
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     //function nodes must be able to work with defined data type
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     //one function can be defined with multiple (but different) number of arguments
00062     uint arg;
00063     map<std::string, std::vector<uint> > args;
00064 
00065     //extract function names and number of their arguments, if number of arguments isn't defined, then
00066     //it's default (some function nodes can't have variable number of arguments, e.g. sin or cos)
00067     names.str("");
00068     names.clear();
00069     names << *((string*) sptr.get());
00070     while (names >> name)
00071     {
00072         //if it isn't function name then it can be number of arguments for the last read function name
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             //some functions may go with many number of arguments, all numbers of arguments must be defined
00085             //after stating the name of that function (in configuration file)
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                 //there can't be defined two or more functions with the same name and the same number
00096                 //of arguments
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     //create function objects
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     //number of possible functions
00150     numFunc = (uint)funcSet->size();
00151 
00152     //extract constants, constants aren't necessary
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     //num of variables = num of inputs to be replaced by elements from domain
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     //if not defined, default is 1
00222     if (name.length() == 0)
00223     {
00224         levelsBack = 1;
00225     }
00226     else
00227     {
00228         levelsBack = str2uint(name);
00229     }
00230 
00231     makeGenotype();
00232 
00233     //printGenotype();
00234 
00235     return true;
00236 }
00237 
00238 Cartesian* Cartesian::copy()
00239 {
00240     Cartesian *newObject = new Cartesian(*this);
00241 
00242     //create new copy of existing genotype
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     // variableset + constantset = terminalset
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     //generate nodes - input connections + one function
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     //generate outputs
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 

Generated on Tue Nov 4 2014 13:04:30 for ECF by  doxygen 1.7.1