1#include "GEPChromosome.h"
2namespace GEPChromosome{
18 std::vector<CrossoverOpP> GEPChromosome::getCrossoverOp()
20 std::vector<CrossoverOpP> crx;
28 std::vector<MutationOpP> GEPChromosome::getMutationOp()
30 std::vector<MutationOpP> mut;
37 void GEPChromosome::registerParameters(StateP state)
39 registerParameter(state,
"headlength", (voidP)(
new uint(1)), ECF::UINT);
40 registerParameter(state,
"genes", (voidP)(
new uint(1)), ECF::UINT);
41 registerParameter(state,
"functionset", (voidP)(
new std::string), ECF::STRING);
42 registerParameter(state,
"terminalset", (voidP)(
new std::string), ECF::STRING);
43 registerParameter(state,
"linkingfunctions", (voidP)(
new std::string), ECF::STRING);
44 registerParameter(state,
"linklength", (voidP)(
new uint(1)), ECF::UINT);
47 void GEPChromosome::generateChromosome(){
49 for (uint i = 0; i < genes; i++){
51 for (uint j = 0; j < headLength; j++) {
53 node->setPrimitive(primitiveSet_->getRandomPrimitive());
54 this->push_back(
static_cast<Tree::NodeP
>(
node));
57 for (uint j = 0; j < tailLength; j++) {
59 node->setPrimitive(primitiveSet_->getRandomTerminal());
60 this->push_back(
static_cast<Tree::NodeP
>(
node));
63 for (uint j = 0; j < dcLength; j++){
65 node->setPrimitive(ercSet_->getRandomTerminal());
66 this->push_back(
static_cast<Tree::NodeP
>(
node));
70 for (uint i = 0; i < linkHeadLength; i++){
72 node->setPrimitive(linkFunctionSet_->getRandomPrimitive());
73 this->push_back(
static_cast<Tree::NodeP
>(
node));
75 for (uint i = 0; i < linkTailLength; i++){
77 node->setPrimitive(linkFunctionSet_->getRandomTerminal());
78 this->push_back(
static_cast<Tree::NodeP
>(
node));
83 bool GEPChromosome::initialize(StateP state)
91 if (!homegep->primitiveSet_){
92 initializeFirst(homegep);
95 this->primitiveSet_ = homegep->primitiveSet_;
96 this->linkFunctionSet_ = homegep->linkFunctionSet_;
97 this->ercSet_ = homegep->ercSet_;
98 this->headLength = homegep->headLength;
99 this->genes = homegep->genes;
100 this->tailLength = homegep->tailLength;
101 this->dcLength = homegep->dcLength;
102 this->geneLength = homegep->geneLength;
103 this->linkHeadLength = homegep->linkHeadLength;
104 this->linkTailLength = homegep->linkTailLength;
106 generateChromosome();
118 home->primitiveSet_->initialize(state_);
119 this->primitiveSet_ = home->primitiveSet_;
122 home->linkFunctionSet_->initialize(state_);
123 this->linkFunctionSet_ = home->linkFunctionSet_;
126 home->ercSet_->initialize(state_);
127 this->ercSet_ = home->ercSet_;
130 voidP sptr = getParameterValue(state_,
"genes");
131 home->genes = *((uint*)sptr.get());
133 if (home->genes < 1) {
134 ECF_LOG_ERROR(state_,
"Gep genotype: number of genes must be >=1");
139 for (
int i = 0; i < (int)userFunctions_.size(); i++) {
140 primitiveSet_->mAllPrimitives_[userFunctions_[i]->getName()] = userFunctions_[i];
146 sptr = getParameterValue(state_,
"functionset");
147 std::stringstream names;
149 names << *((std::string*) sptr.get());
150 while (names >> name) {
151 if (!primitiveSet_->addFunction(name)) {
152 ECF_LOG_ERROR(state_,
"Error: unknown function in function set (\'" + name +
"\')!");
155 tmpArg = primitiveSet_->getPrimitiveByName(name)->getNumberOfArguments();
160 sptr = getParameterValue(state_,
"headlength");
161 home->headLength = *((uint*)sptr.get());
163 if (home->headLength < 1) {
164 ECF_LOG_ERROR(state_,
"Gep genotype: length of head must be >= 1");
168 home->tailLength = home->headLength * (maxArg - 1) + 1;
169 home->geneLength = home->headLength + home->tailLength;
171 if (primitiveSet_->getFunctionSetSize() == 0) {
172 ECF_LOG_ERROR(state_,
"Tree genotype: empty function set!");
182 std::stringstream linkNames;
184 sptr = getParameterValue(state_,
"linkingfunctions");
185 linkNames << *((std::string*) sptr.get());
186 while (linkNames >> name) {
187 if (!linkFunctionSet_->addFunction(name)) {
188 ECF_LOG_ERROR(state_,
"Error: unknown function in linking function set (\'" + name +
"\')!");
191 linkTmpArg = linkFunctionSet_->getPrimitiveByName(name)->getNumberOfArguments();
192 if (linkTmpArg > linkMaxArg)
193 linkMaxArg = linkTmpArg;
196 sptr = getParameterValue(state_,
"linklength");
197 home->linkHeadLength = *((uint*)sptr.get());
199 if (home->linkHeadLength < 1) {
200 ECF_LOG_ERROR(state_,
"Gep genotype: length of linking function gene head must be >= 1");
204 home->linkTailLength = home->linkHeadLength * (linkMaxArg - 1) + 1;
206 if (linkFunctionSet_->getFunctionSetSize() == 0) {
207 ECF_LOG_ERROR(state_,
"GEP genotype: empty linking function set!");
210 for (uint i = 0; i < home->genes; i++){
212 std::string geneTermStr = GEP_GENE_PREFIX;
213 geneTermStr += uint2str(i);
214 geneTerminals->setName(geneTermStr);
215 geneTerminals->initialize(state_);
216 linkFunctionSet_->addTerminal(geneTerminals);
219 Tree::Primitives::terminal_type currentType = Tree::Primitives::Double;
220 Tree::type_iter typeIter;
224 std::stringstream tNames;
225 sptr = getParameterValue(state_,
"terminalset");
226 tNames << *((std::string*) sptr.get());
228 while (tNames >> name) {
230 typeIter = primitiveSet_->mTypeNames_.find(name);
231 if (typeIter != primitiveSet_->mTypeNames_.end()) {
232 currentType = typeIter->second;
252 if (name[0] ==
'[' || name[0] ==
'{') {
258 placeholder->setName(
"?");
259 primitiveSet_->addTerminal(placeholder);
261 home->dcLength = home->tailLength;
262 home->geneLength += home->dcLength;
265 std::string ercValues =
"";
268 Tree::PrimitiveP erc;
269 switch (currentType) {
270 case Tree::Primitives::Double:
272 ercValues = DBL_PREFIX;
274 case Tree::Primitives::Int:
276 ercValues = INT_PREFIX;
278 case Tree::Primitives::Bool:
280 ercValues = BOOL_PREFIX;
282 case Tree::Primitives::Char:
284 ercValues = CHR_PREFIX;
286 case Tree::Primitives::String:
288 ercValues = STR_PREFIX;
292 while (name[name.size() - 1] !=
']' && name[name.size() - 1] !=
'}') {
293 ercValues +=
" " + name;
296 ercValues +=
" " + name;
297 erc->setName(ercValues);
298 erc->initialize(state_);
299 ercSet_->addTerminal(erc);
305 Tree::PrimitiveP terminal;
308 case Tree::Primitives::Double:
310 case Tree::Primitives::Int:
312 case Tree::Primitives::Bool:
314 case Tree::Primitives::Char:
316 case Tree::Primitives::String:
322 std::istringstream ss(name);
325 case Tree::Primitives::Double:
328 if (ss.fail() ==
false)
329 terminal->setValue(&dblValue);
331 case Tree::Primitives::Int:
334 if (ss.fail() ==
false)
335 terminal->setValue(&intValue);
337 case Tree::Primitives::Bool:
342 else if (name ==
"false")
344 if (ss.fail() ==
false || name ==
"true" || name ==
"false") {
349 terminal->setValue(&boolValue);
352 case Tree::Primitives::Char:
355 if (ss.fail() ==
false)
356 terminal->setValue(&charValue);
358 case Tree::Primitives::String:
359 std::string stringValue;
361 if (ss.fail() ==
false)
362 terminal->setValue(&stringValue);
365 terminal->setName(name);
366 primitiveSet_->addTerminal(terminal);
370 if (primitiveSet_->getTerminalSetSize() == 0) {
371 ECF_LOG_ERROR(state_,
"Tree: Empty terminal set!");
378 void GEPChromosome::write(XMLNode &xGEPChromosome)
380 xGEPChromosome = XMLNode::createXMLTopNode(
"GEPChromosome");
381 std::stringstream sValue;
383 xGEPChromosome.addAttribute(
"genes", sValue.str().c_str());
385 sValue << headLength;
386 xGEPChromosome.addAttribute(
"headLength",sValue.str().c_str());
388 sValue << tailLength;
389 xGEPChromosome.addAttribute(
"tailLength", sValue.str().c_str());
391 sValue << linkHeadLength;
392 xGEPChromosome.addAttribute(
"linkLength", sValue.str().c_str());
393 for (uint g = 0; g < genes; g++){
395 XMLNode xGene = XMLNode::createXMLTopNode(
"Gene");
396 for (uint i = 0; i < this->geneLength; i++) {
397 sValue << this->at(g*(this->geneLength)+i)->primitive_->getName() <<
" ";
399 xGene.addText(sValue.str().c_str());
400 xGEPChromosome.addChild(xGene);
404 XMLNode xCell = XMLNode::createXMLTopNode(
"Cell");
405 uint cellOffset = this->genes * this->geneLength;
406 for (uint i = 0; i < this->linkHeadLength + this->linkTailLength; i++) {
407 sValue << this->at(cellOffset + i)->primitive_->getName() <<
" ";
409 xCell.addText(sValue.str().c_str());
410 xGEPChromosome.addChild(xCell);
415 void GEPChromosome::read(XMLNode& xGEPChromosome)
420 XMLCSTR genesStr = xGEPChromosome.getAttribute(
"genes");
421 uint size = str2uint(genesStr);
423 XMLCSTR hlenStr = xGEPChromosome.getAttribute(
"headLength");
424 uint headlen = str2uint(hlenStr);
426 XMLCSTR tlenStr = xGEPChromosome.getAttribute(
"linkLength");
427 uint linklen = str2uint(tlenStr);
429 for (uint i = 0; i <= size; i++){
430 XMLNode xGene = xGEPChromosome.getChildNode(i);
431 XMLCSTR tree = xGene.getText();
432 std::stringstream stream;
436 std::vector<Tree::PrimitiveP>& primitives = primitiveSet_->primitives_;
437 std::string primitiveStr;
440 for (uint iNode = 0; iNode < this->geneLength; iNode++) {
441 stream >> primitiveStr;
445 Tree::PrimitiveP prim = primitiveSet_->getPrimitiveByName(primitiveStr);
446 if (prim != Tree::PrimitiveP()) {
447 node->setPrimitive(prim);
448 this->push_back(
static_cast<Tree::NodeP
>(
node));
453 Tree::PrimitiveP erc;
454 std::string prefix = primitiveStr.substr(0, 2);
455 std::string value = primitiveStr.substr(2);
456 std::stringstream ss;
458 if (prefix == DBL_PREFIX) {
464 else if (prefix == INT_PREFIX) {
470 else if (prefix == BOOL_PREFIX) {
476 else if (prefix == CHR_PREFIX) {
482 else if (prefix == STR_PREFIX) {
489 ECF_LOG_ERROR(state_,
"GEPChromosome genotype: undefined primitive (" + primitiveStr +
")!");
492 erc->setName(primitiveStr);
493 node->primitive_ = erc;
494 this->push_back(
static_cast<Tree::NodeP
>(
node));
498 std::vector<Tree::PrimitiveP>& primitives = linkFunctionSet_->primitives_;
499 std::string primitiveStr;
502 for (uint iNode = 0; iNode < this->linkHeadLength+this->linkTailLength; iNode++) {
503 stream >> primitiveStr;
506 Tree::PrimitiveP prim = linkFunctionSet_->getPrimitiveByName(primitiveStr);
507 if (prim != Tree::PrimitiveP()) {
508 node->setPrimitive(prim);
509 this->push_back(
static_cast<Tree::NodeP
>(
node));
513 ECF_LOG_ERROR(state_,
"GEPChromosome genotype: undefined primitive (" + primitiveStr +
") for the Cell gene!");
522 ECF_LOG(this->state_, 5,
"Performing GEP -> Tree conversion...");
526 tree->primitiveSet_ = this->primitiveSet_;
528 uint geneOffset = gene*(this->geneLength);
529 uint ercIdx = geneOffset + this->headLength + this->tailLength;
534 uint nArgs = this->at(i++)->primitive_->getNumberOfArguments();
536 std::vector<uint> idx;
538 uint nextLevelStart = 1 + geneOffset;
539 idx.push_back(geneOffset);
542 idx.push_back(nextLevelStart);
543 for (uint j = 0; j < nArgs; j++){
544 lvlArity += this->at(nextLevelStart++)->primitive_->getNumberOfArguments();
549 std::vector<int> constants(this->size(), -99999);
550 if (this->dcLength > 0){
551 for (uint c = geneOffset; c < geneOffset + this->headLength + this->tailLength; c++){
552 if (this->at(c)->primitive_->getName() ==
"?"){
553 constants[c] = ercCount++;
559 std::vector<uint> args(idx.size(), 0);
561 std::vector<bool> visited(this->size(),
false);
562 while (idx.at(0) == geneOffset){
564 if (!visited.at(idx.at(level))){
565 Tree::NodeP GEPnode =
static_cast<Tree::NodeP
> (
new Tree::Node(this->at(idx.at(level))));
567 if (GEPnode->primitive_->getName() ==
"?"){
568 GEPnode =
static_cast<Tree::NodeP
> (
new Tree::Node(this->at(ercIdx+constants.at(idx.at(level)))));
570 args[level] = GEPnode->primitive_->getNumberOfArguments();
572 Tree::NodeP
node =
static_cast<Tree::NodeP
> (
new Tree::Node(GEPnode));
574 visited.at(idx.at(level)) =
true;
577 if (args.at(level) > 0){
585 if (level >= 0) args[level]--;
593 char *s = xInd.createXMLString();
594 ECF_LOG(this->state_, 5,
"Tree conversion result: \n" + std::string(s));
600 ECF_LOG(this->state_, 5,
"Performing GEP -> Tree conversion at the cell level...");
604 tree->primitiveSet_ = this->linkFunctionSet_;
606 uint geneOffset = this->genes*(this->geneLength);
609 uint nArgs = this->at(i++)->primitive_->getNumberOfArguments();
611 std::vector<uint> idx;
613 uint nextLevelStart = 1 + geneOffset;
614 idx.push_back(geneOffset);
617 idx.push_back(nextLevelStart);
618 for (uint j = 0; j < nArgs; j++){
619 lvlArity += this->at(nextLevelStart++)->primitive_->getNumberOfArguments();
625 std::vector<uint> args(idx.size(), 0);
627 std::vector<bool> visited(this->size(),
false);
628 while (idx.at(0) == geneOffset){
630 if (!visited.at(idx.at(level))){
631 Tree::NodeP GEPnode =
static_cast<Tree::NodeP
> (
new Tree::Node(this->at(idx.at(level))));
632 args[level] = GEPnode->primitive_->getNumberOfArguments();
634 Tree::NodeP
node =
static_cast<Tree::NodeP
> (
new Tree::Node(GEPnode));
636 visited.at(idx.at(level)) =
true;
639 if (args.at(level) > 0){
647 if (level >= 0) args[level]--;
655 char *s = xInd.createXMLString();
656 ECF_LOG(this->state_, 5,
"Tree conversion result: \n" + std::string(s));
660 void GEPChromosome::assemble(){
661 this->subtrees.clear();
662 this->cellTree = this->makeCellTree();
663 for (uint i = 0; i < this->genes; i++){
665 this->subtrees.push_back(subtree);
669 void GEPChromosome::execute(
void *result){
675 for (uint i = 0; i < this->genes; i++){
679 this->cellTree->setTerminalValue(GEP_GENE_PREFIX + uint2str(i), &tmp);
682 this->cellTree->execute(result);
691 void GEPChromosome::setTerminalValue(std::string name,
void* value)
693 Tree::PrimitiveP term = primitiveSet_->getTerminalByName(name);
694 if (term == Tree::PrimitiveP()) {
695 ECF_LOG_ERROR(state_,
"GEPChromosome genotype: invalid terminal name referenced in setTerminalValue()!");
699 term->setValue(value);
GEPChromosome genotype: gene crx operator. Selects a gene number and swaps it between both parents.
GEPChromosome genotype: one point crx operator. Selects a crossing point from which to exchange genet...
GEPChromosome genotype: two point crx operator. Selects two crossing points between which to exchange...
GEPChromosome class - implements genotype as a Gene Expression Programming chromosome.
GEPChromosome genotype: standard normal distribution noise mutation operator. Applicable only on ephe...
GEPChromosome genotype: node replacement mutation operator. Tries to replace the selected primitive w...
std::string name_
genotype's name
Node base class (Tree genotype)
Primitive set class: collects all Tree Primitives.
Ephemereal random constant (ERC) node of type double (Tree genotype).
Ephemereal random constant (ERC) node class (Tree genotype).
Terminal tree node class (Tree genotype).
Tree class - implements genotype as a tree.
void write(XMLNode &)
Write genotype data to XMLNode.
void update()
Calculate depth and subtree sizes of each node in the tree.
void execute(void *)
Execute current tree.