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

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

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

Generated on Fri Jul 5 2013 09:34:23 for ECF by  doxygen 1.7.1