void Genome::mutate_add_sensor(Vector &innovs,double &curinnov) { Vector sensors; Vector outputs; NNode *node; NNode *sensor; NNode *output; Gene *gene; double newweight; Gene *newgene; int i,j; //counters bool found; bool done; int outputConnections; Vector::iterator thetrait; int traitnum; Vector::iterator theinnov; //For finding a historical match //Find all the sensors and outputs for (i = 0; i < nodes.size(); i++) { node=nodes[i]; if ((node->type)==SENSOR) sensors.push_back(node); else if (node->gen_node_label == OUTPUT) outputs.push_back(node); } // eliminate from contention any sensors that are already connected for (i = 0; i < sensors.size(); i++) { sensor=sensors[i]; outputConnections=0; for (int j = 0; j < genes.size(); j++) { gene=genes[j]; if ((gene->lnk)->out_node->gen_node_label == OUTPUT) outputConnections++; } if (outputConnections == outputs.size()) { sensors.erase(i); //Does this work? remove by number from a vector? --i; } } //If all sensors are connected, quit if (sensors.size() == 0) return; //Pick randomly from remaining sensors sensor=sensors[randint(0,sensors.size()-1)]; //Add new links to chosen sensor, avoiding redundancy for (int i = 0; i < outputs.size(); i++) { output=outputs[i]; found=false; for (j = 0; j < genes.size(); j++) { gene=genes[j]; if ((gene->lnk->in_node==sensor)&& (gene->lnk->out_node==output)) found=true; } //Record the innovation if (!found) { theinnov=innovs.begin(); done=false; while (!done) { //The innovation is novel if (theinnov==innovs.end()) { //Choose a random trait traitnum=randint(0,(traits.size())-1); thetrait=traits.begin(); //Choose the new weight //newweight=(gaussrand())/1.5; //Could use a gaussian newweight=randposneg()*randfloat()*3.0; //used to be 10.0 //Create the new gene newgene=new Gene(((thetrait[traitnum])), newweight,sensor,output,false, curinnov,newweight); //Add the innovation innovs.push_back(new Innovation(sensor->node_id, output->node_id,curinnov,newweight,traitnum)); curinnov=curinnov+1.0; done=true; } //end novel innovation case //OTHERWISE, match the innovation in the innovs list else if (((*theinnov)->innovation_type==NEWLINK)&& ((*theinnov)->node_in_id==(sensor->node_id))&& ((*theinnov)->node_out_id==(output->node_id))&& ((*theinnov)->recur_flag==false)) { thetrait=traits.begin(); //Create new gene newgene= new Gene(((thetrait[(*theinnov)->new_traitnum])), (*theinnov)->new_weight,sensor,output, false,(*theinnov)->innovation_num1,0); done=true; } //end prior innovation case //Keep looking for matching innovation else ++theinnov; } //end while genes.push_back(newgene); } //end case where the gene didn't previously exist } }