Gene

genomestart 1

trait 1 0.1 0 0 0 0 0 0 0

trait 2 0.2 0 0 0 0 0 0 0

trait 3 0.3 0 0 0 0 0 0 0

node 1 0 1 3

node 2 0 1 1

node 3 0 1 1

node 4 0 0 2

gene 1 1 4 0.0 0 1 0 1

gene 2 2 4 0.0 0 2 0 1

gene 3 3 4 0.0 0 3 0 1

genomeend 1

///////////////////////////////////////////////////////////////////////////////////////

#ifndef _GENE_H_

#define _GENE_H_

#include "neat.h"

#include "trait.h"

#include "link.h"

#include "network.h"

namespace NEAT {

class Gene {

public:

Link *lnk;

double innovation_num;

double mutation_num;  //Used to see how much mutation has changed the link

bool enable;  //When this is off the Gene is disabled

bool frozen;  //When frozen, the linkweight cannot be mutated

//Construct a gene with no trait

Gene(double w,NNode *inode,NNode *onode,bool recur,double innov,double mnum);

//Construct a gene with a trait

Gene(Trait *tp,double w,NNode *inode,NNode *onode,bool recur,double innov,double mnum);

//Construct a gene off of another gene as a duplicate

Gene(Gene *g,Trait *tp,NNode *inode,NNode *onode);

//Construct a gene from a file spec given traits and nodes

Gene(const char *argline, std::vector<Trait*> &traits, std::vector<NNode*> &nodes);

// Copy Constructor

Gene(const Gene& gene);

~Gene();

//Print gene to a file- called from Genome

        void print_to_file(std::ostream &outFile);

void print_to_file(std::ofstream &outFile);

};

} // namespace NEAT

#endif

////////////////////////////////////////////////////////////////////////////////////////

#include "gene.h"

#include <iostream>

#include <sstream>

using namespace NEAT;

Gene::Gene(double w, NNode *inode, NNode *onode, bool recur, double innov, double mnum) {

lnk = new Link(w, inode, onode, recur);

innovation_num = innov;

mutation_num = mnum;

enable = true;

frozen = false;

}

Gene::Gene(Trait *tp,double w,NNode *inode,NNode *onode,bool recur,double innov,double mnum) {

lnk=new Link(tp,w,inode,onode,recur);

innovation_num=innov;

mutation_num=mnum;

enable=true;

frozen=false;

}

Gene::Gene(Gene *g,Trait *tp,NNode *inode,NNode *onode) {

//cout<<"Trying to attach nodes: "<<inode<<" "<<onode<<endl;

lnk=new Link(tp,(g->lnk)->weight,inode,onode,(g->lnk)->is_recurrent);

innovation_num=g->innovation_num;

mutation_num=g->mutation_num;

enable=g->enable;

frozen=g->frozen;

}

Gene::Gene(const char *argline, std::vector<Trait*> &traits, std::vector<NNode*> &nodes) {

//Gene parameter holders

int traitnum;

int inodenum;

int onodenum;

NNode *inode;

NNode *onode;

double weight;

int recur;

Trait *traitptr;

std::vector<Trait*>::iterator curtrait;

std::vector<NNode*>::iterator curnode;

//Get the gene parameters

    std::stringstream ss(argline);

//char curword[128];

//char delimiters[] = " \n";

//int curwordnum = 0;

//strcpy(curword, NEAT::getUnit(argline, curwordnum++, delimiters));

//traitnum = atoi(curword);

//strcpy(curword, NEAT::getUnit(argline, curwordnum++, delimiters));

//inodenum = atoi(curword);

//strcpy(curword, NEAT::getUnit(argline, curwordnum++, delimiters));

//onodenum = atoi(curword);

//strcpy(curword, NEAT::getUnit(argline, curwordnum++, delimiters));

//weight = atof(curword);

//strcpy(curword, NEAT::getUnit(argline, curwordnum++, delimiters));

//recur = atoi(curword);

//strcpy(curword, NEAT::getUnit(argline, curwordnum++, delimiters));

//innovation_num = atof(curword);

//strcpy(curword, NEAT::getUnit(argline, curwordnum++, delimiters));

//mutation_num = atof(curword);

//strcpy(curword, NEAT::getUnit(argline, curwordnum++, delimiters));

//enable = (bool)(atoi(curword));

    ss >> traitnum >> inodenum >> onodenum >> weight >> recur >> innovation_num >> mutation_num >> enable;

    //std::cout << traitnum << " " << inodenum << " " << onodenum << " ";

    //std::cout << weight << " " << recur << " " << innovation_num << " ";

    //std::cout << mutation_num << " " << enable << std::endl;

frozen=false; //TODO: MAYBE CHANGE

//Get a pointer to the linktrait

if (traitnum==0) traitptr=0;

else {

curtrait=traits.begin();

while(((*curtrait)->trait_id)!=traitnum)

++curtrait;

traitptr=(*curtrait);

}

//Get a pointer to the input node

curnode=nodes.begin();

while(((*curnode)->node_id)!=inodenum)

++curnode;

inode=(*curnode);

//Get a pointer to the output node

curnode=nodes.begin();

while(((*curnode)->node_id)!=onodenum)

++curnode;

onode=(*curnode);

lnk=new Link(traitptr,weight,inode,onode,recur);

}

Gene::Gene(const Gene& gene)

{

innovation_num = gene.innovation_num;

mutation_num = gene.mutation_num;

enable = gene.enable;

frozen = gene.frozen;

lnk = new Link(*gene.lnk);

}

Gene::~Gene() {

delete lnk;

}

void Gene::print_to_file(std::ofstream &outFile) {

  outFile<<"gene ";

  //Start off with the trait number for this gene

  if ((lnk->linktrait)==0) outFile<<"0 ";

  else outFile<<((lnk->linktrait)->trait_id)<<" ";

  outFile<<(lnk->in_node)->node_id<<" ";

  outFile<<(lnk->out_node)->node_id<<" ";

  outFile<<(lnk->weight)<<" ";

  outFile<<(lnk->is_recurrent)<<" ";

  outFile<<innovation_num<<" ";

  outFile<<mutation_num<<" ";

  outFile<<enable<<std::endl;

}

void Gene::print_to_file(std::ostream &outFile) {

outFile<<"gene ";

//outFile.write(5, "gene ");

//Start off with the trait number for this gene

if ((lnk->linktrait)==0) {

outFile<<"0 ";

//outFile.write(2, "0 ");

}

else {

outFile<<((lnk->linktrait)->trait_id)<<" ";

//char tempbuf2[128];

//sprintf(tempbuf2, sizeof(tempbuf2),"%d ", (lnk->linktrait)->trait_id);

//outFile.write(strlen(tempbuf2),tempbuf2);

}

//char tempbuf[1024];

//sprintf(tempbuf,sizeof(tempbuf),"%d %d %f %d %f %f %d\n", (lnk->in_node)->node_id,

// (lnk->out_node)->node_id, lnk->weight, lnk->is_recurrent, innovation_num, mutation_num, enable);

//outFile.write(strlen(tempbuf),tempbuf);

outFile<<(lnk->in_node)->node_id<<" ";

outFile<<(lnk->out_node)->node_id<<" ";

outFile<<(lnk->weight)<<" ";

outFile<<(lnk->is_recurrent)<<" ";

outFile<<innovation_num<<" ";

outFile<<mutation_num<<" ";

    outFile<<enable<<std::endl;

}