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.