7#include "CartesianCrxOnePoint.h"
8#include "CartesianCrxHalfUniform.h"
9#include "CartesianCrxUniform.h"
12#include "CartesianMutOnePoint.h"
13#include "CartesianMutNonSilent.h"
14#include "CartesianMutOnePointActive.h"
20Cartesian::Cartesian(
void)
27Cartesian::~Cartesian(
void)
33 Cartesian *newObject =
new Cartesian(*
this);
40 std::vector<CrossoverOpP> crxOps;
50 std::vector<MutationOpP> mutOps;
60 registerParameter(state,
"numoutputs", (voidP) (
new uint(1)), ECF::UINT,
"number of functional outputs (default: 1)");
61 registerParameter(state,
"numrows", (voidP) (
new uint(1)), ECF::UINT,
"number of rows (default: 1)");
62 registerParameter(state,
"numcols", (voidP) (
new uint(10)), ECF::UINT,
"number of columns (default: 10)");
63 registerParameter(state,
"levelsback", (voidP) (
new uint(2)), ECF::UINT,
"number of previous columns to be used as possible inputs (default: 2)");
64 registerParameter(state,
"numvariables", (voidP) (
new uint(1)), ECF::UINT,
"number of input variables (default: 1)");
65 registerParameter(state,
"functionset", (voidP) (
new std::string), ECF::STRING,
"set of functions to use (mandatory)");
66 registerParameter(state,
"constantset", (voidP)(
new std::string), ECF::STRING,
"set of input constants (default: none)");
74 std::string names,name;
78 names = *((std::string*)sptr.get());
81 ECF_LOG_ERROR(state,
"Cartesian initialization error: required parameters for CGP genotype not defined (functionset)!");
92 number = *((uint*) sptr.get());
94 ECF_LOG_ERROR(state,
"Cartesian initialization error: Number of variables is smaller than 1 or cannot be parsed into a number.");
100 number = *((uint*) sptr.get());
102 ECF_LOG_ERROR(state,
"Cartesian initialization error: Number of outputs is smaller than 1 or cannot be parsed into a number.");
108 number = *((uint*) sptr.get());
110 ECF_LOG_ERROR(state,
"Cartesian initialization error: Number of rows is smaller than 1 or cannot be parsed into a number.");
116 number = *((uint*) sptr.get());
118 ECF_LOG_ERROR(state,
"Cartesian initialization error: Number of columns is smaller than 1 or cannot be parsed into a number.");
124 number = *((uint*) sptr.get());
126 ECF_LOG_ERROR(state,
"Cartesian initialization error: Number of columns is smaller than 1 or cannot be parsed into a number.");
135 names = *((std::string*)sptr.get());
140 std::istringstream token(name);
142 if (token >> value) {
152 names = *((std::string*) sptr.get());
163 ECF_LOG_ERROR(state,
"Cartesian initialization error: unknown function (\"" + name +
"\")");
168 ECF_LOG_ERROR(state,
"Cartesian initialization error: no valid functions in functionset");
173 std::map<std::string, uint>::iterator it;
175 uint nArgs =
functionSet_->vFunctions[it->second]->getNumberOfArguments();
188 std::string s = xCart.getText(0);
189 std::istringstream ss(s);
196 if (token[0] !=
'(') {
202 std::map <std::string, unsigned int>::iterator it =
functionSet_->mFunctionSet.find(token);
204 ECF_LOG_ERROR(
state_,
"Cartesian genotype: unused function (" + token +
")!");
205 throw std::runtime_error(
"Cartesian genotype: unused function (" + token +
")!");
210 uint nArgs =
functionSet_->vFunctions[it->second]->getNumberOfArguments();
211 nodes_[iNode].arguments_.resize(nArgs);
213 for (uint arg = 0; arg < nArgs; arg++) {
215 nodes_[iNode].arguments_[arg] = stoi(token);
225 xCart = XMLNode::createXMLTopNode(
"Cartesian");
226 std::stringstream sValue;
228 xCart.addAttribute(
"size", sValue.str().c_str());
234 sValue <<
"(" <<
nodes_[iNode].primitive_->getName() <<
" ";
235 uint nArgs = (uint)
nodes_[iNode].arguments_.size();
236 for (uint i = 0; i < nArgs; i++) {
237 sValue <<
nodes_[iNode].arguments_[i];
243 for (uint i = 0; i <
outputs_.size(); i++)
246 xCart.addText(sValue.str().c_str());
261 for (uint iCol = 0; iCol <
nCols_; iCol++) {
262 for(uint j = 0; j <
nRows_; j++) {
268 newNode.setPrimitive(
functionSet_->vFunctions[functionID]);
271 FunctionP function =
functionSet_->vFunctions[functionID];
272 for (uint k = 0; k < function->getNumberOfArguments(); k++) {
274 newNode.arguments_.push_back(iArgument);
276 nodes_.push_back(newNode);
298 uint nPreviousFunctionNodes = firstNodeInColumn - firstAllowedNode;
300 uint nCandidates =
nInputs_ + nPreviousFunctionNodes;
302 uint
id =
state_->getRandomizer()->getRandomInteger(nCandidates);
309 return firstAllowedNode + (
id -
nInputs_);
322 throw std::runtime_error(
"Cartesian error: inputData vector size not equal to number of input variables.");
325 std::vector<double> node_values(inputData);
329 std::vector<double> operands(this->
maxArity_);
333 int numberOfArguments =
nodes_[i].primitive_->getNumberOfArguments();
334 for(
int k = 0; k < numberOfArguments; k++) {
335 operands[k] = node_values[
nodes_[i].arguments_[k]];
337 nodes_[i].primitive_->evaluate(operands, result);
338 node_values.push_back(result);
342 for (uint i = 0; i <
outputs_.size(); i++) {
343 results[i] = node_values[
outputs_[i]];
350 const uint size = (uint)
nodes_.size();
351 std::vector<bool> activeFlags(size,
false);
356 activeFlags[i] =
true;
357 addRecursivelyActiveFunctionNodes(activeFlags, i);
361 for (uint i =
nInputs_; i < activeFlags.size(); i++)
363 activeNodes.push_back(i);
367void Cartesian::addRecursivelyActiveFunctionNodes(std::vector<bool>& activeFlags, uint node)
369 for (uint iArg = 0; iArg < nodes_[node].primitive_->getNumberOfArguments(); iArg++) {
370 uint iActive = nodes_[node].arguments_[iArg];
372 if (iActive >= nInputs_ && activeFlags[iActive] ==
false) {
373 activeFlags[iActive] =
true;
374 addRecursivelyActiveFunctionNodes(activeFlags, iActive);
Cartesian genotype: one point crossover operator.
uint nVariables_
number of input variables
void read(XMLNode &xCart)
StateP state_
local copy of state
uint nRows_
number of rows
uint nFunctions_
number of used functions
uint nInputs_
total number of inputs (variables and constants)
uint nCols_
number of columns
void evaluate(std::vector< double > &inputData, std::vector< double > &results)
uint randomNodeInputConnection(uint column)
std::vector< MutationOpP > getMutationOp()
FunctionSetP functionSet_
pointer to function set
std::vector< double > constants_
input nodes with constant values
uint randomOutputConnection()
void getActiveFunctionNodes(std::vector< uint > &)
uint maxArity_
max number of inputs for all function nodes
uint nLevelsBack_
levels back parameter
void registerParameters(StateP state)
bool initialize(StateP state)
uint nConstants_
number of input constants
std::vector< CrossoverOpP > getCrossoverOp()
std::vector< uint > outputs_
output nodes
void write(XMLNode &xCart)
uint nOutputs_
number of final outputs
std::vector< Node > nodes_
genotype nodes (input nodes and function nodes)
voidP getParameterValue(StateP state, std::string name)
Read single parameter value from Registry.
bool registerParameter(StateP state, std::string name, voidP value, enum ECF::type T, std::string description="")
Register a single parameter.
bool isParameterDefined(StateP state, std::string name)
Check if parameter is defined in the configuration.