1#include "GEPChromosome.h"
5 GEPChromosome::GEPChromosome(){
15 GEPChromosome *newObject =
new GEPChromosome(*
this);
22 std::vector<CrossoverOpP> crx;
32 std::vector<MutationOpP> mut;
45 registerParameter(state,
"linkingfunctions", (voidP)(
new std::string), ECF::STRING);
56 userFunctions_.push_back(func);
61 void GEPChromosome::generateChromosome()
64 for (uint i = 0; i <
genes; i++){
69 this->push_back(
static_cast<Tree::NodeP
>(node));
75 this->push_back(
static_cast<Tree::NodeP
>(node));
79 node =
new Tree::Node();
81 this->push_back(
static_cast<Tree::NodeP
>(node));
86 node =
new Tree::Node();
87 node->
setPrimitive(linkFunctionSet_->getRandomPrimitive());
88 this->push_back(
static_cast<Tree::NodeP
>(node));
91 node =
new Tree::Node();
92 node->
setPrimitive(linkFunctionSet_->getRandomTerminal());
93 this->push_back(
static_cast<Tree::NodeP
>(node));
102 GEPChromosome* homegep = (GEPChromosome*)state->getGenotypes()[
genotypeId_].get();
106 if (!homegep->primitiveSet_){
107 initializeFirst(homegep);
110 this->primitiveSet_ = homegep->primitiveSet_;
111 this->linkFunctionSet_ = homegep->linkFunctionSet_;
112 this->ercSet_ = homegep->ercSet_;
114 this->genes = homegep->
genes;
121 generateChromosome();
134 home->primitiveSet_->initialize(state_);
135 this->primitiveSet_ = home->primitiveSet_;
138 home->linkFunctionSet_->initialize(state_);
139 this->linkFunctionSet_ = home->linkFunctionSet_;
142 home->ercSet_->initialize(state_);
143 this->ercSet_ = home->ercSet_;
147 home->
genes = *((uint*)sptr.get());
149 if (home->
genes < 1) {
150 ECF_LOG_ERROR(state_,
"Gep genotype: number of genes must be >=1");
155 for (
int i = 0; i < (int)userFunctions_.size(); i++) {
156 primitiveSet_->mAllPrimitives_[userFunctions_[i]->getName()] = userFunctions_[i];
163 std::stringstream names;
165 names << *((std::string*) sptr.get());
166 while (names >> name) {
167 if (!primitiveSet_->addFunction(name)) {
168 ECF_LOG_ERROR(state_,
"Error: unknown function in function set (\'" + name +
"\')!");
171 tmpArg = primitiveSet_->getPrimitiveByName(name)->getNumberOfArguments();
180 ECF_LOG_ERROR(state_,
"Gep genotype: length of head must be >= 1");
187 if (primitiveSet_->getFunctionSetSize() == 0) {
188 ECF_LOG_ERROR(state_,
"Tree genotype: empty function set!");
198 std::stringstream linkNames;
201 linkNames << *((std::string*) sptr.get());
202 while (linkNames >> name) {
203 if (!linkFunctionSet_->addFunction(name)) {
204 ECF_LOG_ERROR(state_,
"Error: unknown function in linking function set (\'" + name +
"\')!");
207 linkTmpArg = linkFunctionSet_->getPrimitiveByName(name)->getNumberOfArguments();
208 if (linkTmpArg > linkMaxArg)
209 linkMaxArg = linkTmpArg;
216 ECF_LOG_ERROR(state_,
"Gep genotype: length of linking function gene head must be >= 1");
222 if (linkFunctionSet_->getFunctionSetSize() == 0) {
223 ECF_LOG_ERROR(state_,
"GEP genotype: empty linking function set!");
226 for (uint i = 0; i < home->
genes; i++){
227 Tree::PrimitiveP geneTerminals = (Tree::PrimitiveP)(
new Tree::Primitives::Terminal);
228 std::string geneTermStr = GEP_GENE_PREFIX;
229 geneTermStr += uint2str(i);
230 geneTerminals->setName(geneTermStr);
231 geneTerminals->initialize(state_);
232 linkFunctionSet_->addTerminal(geneTerminals);
235 Tree::Primitives::terminal_type currentType = Tree::Primitives::Double;
236 Tree::type_iter typeIter;
240 std::stringstream tNames;
242 tNames << *((std::string*) sptr.get());
244 while (tNames >> name) {
246 typeIter = primitiveSet_->mTypeNames_.find(name);
247 if (typeIter != primitiveSet_->mTypeNames_.end()) {
248 currentType = typeIter->second;
268 if (name[0] ==
'[' || name[0] ==
'{') {
273 Tree::PrimitiveP placeholder = (Tree::PrimitiveP) (
new Tree::Primitives::Terminal);
274 placeholder->setName(
"?");
275 primitiveSet_->addTerminal(placeholder);
281 std::string ercValues =
"";
284 Tree::PrimitiveP erc;
285 switch (currentType) {
286 case Tree::Primitives::Double:
287 erc = (Tree::PrimitiveP)(
new Tree::Primitives::ERCD);
288 ercValues = DBL_PREFIX;
290 case Tree::Primitives::Int:
291 erc = (Tree::PrimitiveP)(
new Tree::Primitives::ERC<int>);
292 ercValues = INT_PREFIX;
294 case Tree::Primitives::Bool:
295 erc = (Tree::PrimitiveP)(
new Tree::Primitives::ERC<bool>);
296 ercValues = BOOL_PREFIX;
298 case Tree::Primitives::Char:
299 erc = (Tree::PrimitiveP)(
new Tree::Primitives::ERC<char>);
300 ercValues = CHR_PREFIX;
302 case Tree::Primitives::String:
303 erc = (Tree::PrimitiveP)(
new Tree::Primitives::ERC<std::string>);
304 ercValues = STR_PREFIX;
308 while (name[name.size() - 1] !=
']' && name[name.size() - 1] !=
'}') {
309 ercValues +=
" " + name;
312 ercValues +=
" " + name;
313 erc->setName(ercValues);
314 erc->initialize(state_);
315 ercSet_->addTerminal(erc);
321 Tree::PrimitiveP terminal;
324 case Tree::Primitives::Double:
325 terminal = (Tree::PrimitiveP) (
new Tree::Primitives::Terminal);
break;
326 case Tree::Primitives::Int:
327 terminal = (Tree::PrimitiveP) (
new Tree::Primitives::TerminalT<int>);
break;
328 case Tree::Primitives::Bool:
329 terminal = (Tree::PrimitiveP) (
new Tree::Primitives::TerminalT<bool>);
break;
330 case Tree::Primitives::Char:
331 terminal = (Tree::PrimitiveP) (
new Tree::Primitives::TerminalT<char>);
break;
332 case Tree::Primitives::String:
333 terminal = (Tree::PrimitiveP) (
new Tree::Primitives::TerminalT<std::string>);
break;
338 std::istringstream ss(name);
341 case Tree::Primitives::Double:
344 if (ss.fail() ==
false)
345 terminal->setValue(&dblValue);
347 case Tree::Primitives::Int:
350 if (ss.fail() ==
false)
351 terminal->setValue(&intValue);
353 case Tree::Primitives::Bool:
358 else if (name ==
"false")
360 if (ss.fail() ==
false || name ==
"true" || name ==
"false") {
365 terminal->setValue(&boolValue);
368 case Tree::Primitives::Char:
371 if (ss.fail() ==
false)
372 terminal->setValue(&charValue);
374 case Tree::Primitives::String:
375 std::string stringValue;
377 if (ss.fail() ==
false)
378 terminal->setValue(&stringValue);
381 terminal->setName(name);
382 primitiveSet_->addTerminal(terminal);
386 if (primitiveSet_->getTerminalSetSize() == 0) {
387 ECF_LOG_ERROR(state_,
"Tree: Empty terminal set!");
396 xGEPChromosome = XMLNode::createXMLTopNode(
"GEPChromosome");
397 std::stringstream sValue;
399 xGEPChromosome.addAttribute(
"genes", sValue.str().c_str());
402 xGEPChromosome.addAttribute(
"headLength",sValue.str().c_str());
405 xGEPChromosome.addAttribute(
"tailLength", sValue.str().c_str());
408 xGEPChromosome.addAttribute(
"linkLength", sValue.str().c_str());
409 for (uint g = 0; g <
genes; g++){
411 XMLNode xGene = XMLNode::createXMLTopNode(
"Gene");
413 sValue << this->at(g*(this->geneLength)+i)->primitive_->getName() <<
" ";
415 xGene.addText(sValue.str().c_str());
416 xGEPChromosome.addChild(xGene);
420 XMLNode xCell = XMLNode::createXMLTopNode(
"Cell");
421 uint cellOffset = this->genes * this->
geneLength;
422 for (uint i = 0; i < this->linkHeadLength + this->linkTailLength; i++) {
423 sValue << this->at(cellOffset + i)->primitive_->getName() <<
" ";
425 xCell.addText(sValue.str().c_str());
426 xGEPChromosome.addChild(xCell);
545 ECF_LOG(this->state_, 5,
"Performing GEP -> Tree conversion...");
549 tree->primitiveSet_ = this->primitiveSet_;
552 uint ercIdx = geneOffset + this->headLength + this->tailLength;
557 uint nArgs = this->at(i++)->primitive_->getNumberOfArguments();
559 std::vector<uint> idx;
561 uint nextLevelStart = 1 + geneOffset;
562 idx.push_back(geneOffset);
565 idx.push_back(nextLevelStart);
566 for (uint j = 0; j < nArgs; j++){
567 lvlArity += this->at(nextLevelStart++)->primitive_->getNumberOfArguments();
572 std::vector<int> constants(this->size(), -99999);
575 if (this->at(c)->primitive_->getName() ==
"?"){
576 constants[c] = ercCount++;
582 std::vector<uint> args(idx.size(), 0);
584 std::vector<bool> visited(this->size(),
false);
585 while (idx.at(0) == geneOffset){
587 if (!visited.at(idx.at(level))){
588 Tree::NodeP GEPnode =
static_cast<Tree::NodeP
> (
new Tree::Node(this->at(idx.at(level))));
590 if (GEPnode->primitive_->getName() ==
"?"){
591 GEPnode =
static_cast<Tree::NodeP
> (
new Tree::Node(this->at(ercIdx+constants.at(idx.at(level)))));
593 args[level] = GEPnode->primitive_->getNumberOfArguments();
595 Tree::NodeP node =
static_cast<Tree::NodeP
> (
new Tree::Node(GEPnode));
597 visited.at(idx.at(level)) =
true;
600 if (args.at(level) > 0){
608 if (level >= 0) args[level]--;
616 char *s = xInd.createXMLString();
617 ECF_LOG(this->state_, 5,
"Tree conversion result: \n" + std::string(s));
622 Tree::Tree* GEPChromosome::makeCellTree()
624 ECF_LOG(this->state_, 5,
"Performing GEP -> Tree conversion at the cell level...");
626 Tree::Tree* tree =
new Tree::Tree();
628 tree->primitiveSet_ = this->linkFunctionSet_;
633 uint nArgs = this->at(i++)->primitive_->getNumberOfArguments();
635 std::vector<uint> idx;
637 uint nextLevelStart = 1 + geneOffset;
638 idx.push_back(geneOffset);
641 idx.push_back(nextLevelStart);
642 for (uint j = 0; j < nArgs; j++){
643 lvlArity += this->at(nextLevelStart++)->primitive_->getNumberOfArguments();
649 std::vector<uint> args(idx.size(), 0);
651 std::vector<bool> visited(this->size(),
false);
652 while (idx.at(0) == geneOffset){
654 if (!visited.at(idx.at(level))){
655 Tree::NodeP GEPnode =
static_cast<Tree::NodeP
> (
new Tree::Node(this->at(idx.at(level))));
656 args[level] = GEPnode->primitive_->getNumberOfArguments();
658 Tree::NodeP node =
static_cast<Tree::NodeP
> (
new Tree::Node(GEPnode));
660 visited.at(idx.at(level)) =
true;
663 if (args.at(level) > 0){
671 if (level >= 0) args[level]--;
679 char *s = xInd.createXMLString();
680 ECF_LOG(this->state_, 5,
"Tree conversion result: \n" + std::string(s));
684 void GEPChromosome::assemble(){
685 this->subtrees.clear();
686 this->cellTree = this->makeCellTree();
687 for (uint i = 0; i < this->
genes; i++){
688 Tree::Tree *subtree = this->toTree(i);
689 this->subtrees.push_back(subtree);
693 void GEPChromosome::execute(
void *result)
700 for (uint i = 0; i < this->
genes; i++){
701 Tree::Tree *subtree = this->subtrees.at(i);
704 this->cellTree->setTerminalValue(GEP_GENE_PREFIX + uint2str(i), &tmp);
707 this->cellTree->execute(result);
718 Tree::PrimitiveP term = primitiveSet_->getTerminalByName(name);
719 if (term == Tree::PrimitiveP()) {
720 ECF_LOG_ERROR(state_,
"GEPChromosome genotype: invalid terminal name referenced in setTerminalValue()!");
724 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.
uint genes
number of genes
void read(XMLNode &xGEPChromosomeInd)
Read genotype data from XMLNode.
bool initialize(StateP state)
Initialize a genotype object (read parameters, perform sanity check, build data).
bool usesERC
whether or not the chromosome uses random constants
std::vector< CrossoverOpP > getCrossoverOp()
Create and return a vector of crossover operators.
void write(XMLNode &xGEPChromosome)
Write genotype data to XMLNode.
uint tailLength
length of the tail. Automatically calculated.
GEPChromosome * copy()
Create an identical copy of the genotype object.
uint linkTailLength
length of the linking function gene's tail
uint geneLength
total length of each gene
void setTerminalValue(std::string name, void *value)
Set a terminal's value.
uint linkHeadLength
length of the linking function gene's head
uint dcLength
length of the constant values domain
uint headLength
length of the head. User-specified
void registerParameters(StateP state)
Register genotype's parameters (called before Genotype::initialize).
std::vector< MutationOpP > getMutationOp()
Create and return a vector of mutation operators.
bool addFunction(Tree::PrimitiveP func)
Add user defined function primitive. Must be called prior to initialization (no impact otherwise).
bool staticLink
whether we are using a static linking function or if it should be allowed to evolve
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...
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.
std::string name_
genotype's name
uint genotypeId_
this genotype's unique index in individual structure
Node base class (Tree genotype).
void setPrimitive(PrimitiveP primitive)
Set the primitive this node points to (when creating a new tree node). In case of an ephemereal rando...
Primitive set class: collects all Tree Primitives.
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.