예제 #1
0
bool Species::reproduce(int generation, Population *pop,std::vector<Species*> &sorted_species) {
	int count;
	std::vector<Organism*>::iterator curorg;

	int poolsize;  //The number of Organisms in the old generation

	int orgnum;  //Random variable
	int orgcount;
	Organism *mom; //Parent Organisms
	Organism *dad;
	Organism *baby;  //The new Organism

	Genome *new_genome;  //For holding baby's genes

	std::vector<Species*>::iterator curspecies;  //For adding baby
	Species *newspecies; //For babies in new Species
	Organism *comporg;  //For Species determination through comparison

	Species *randspecies;  //For mating outside the Species
	double randmult;
	int randspeciesnum;
	int spcount;  
	std::vector<Species*>::iterator cursp;

	Network *net_analogue;  //For adding link to test for recurrency
	int pause;

	bool outside;

	bool found;  //When a Species is found

	bool champ_done=false; //Flag the preservation of the champion  

	Organism *thechamp;

	int giveup; //For giving up finding a mate outside the species

	bool mut_struct_baby;
	bool mate_baby;

	//The weight mutation power is species specific depending on its age
	double mut_power=NEAT::weight_mut_power;

	//Roulette wheel variables
	double total_fitness=0.0;
	double marble;  //The marble will have a number between 0 and total_fitness
	double spin;  //0Fitness total while the wheel is spinning

	//Compute total fitness of species for a roulette wheel
	//Note: You don't get much advantage from a roulette here
	// because the size of a species is relatively small.
	// But you can use it by using the roulette code here
	//for(curorg=organisms.begin();curorg!=organisms.end();++curorg) {
	//  total_fitness+=(*curorg)->fitness;
	//}

	
	//Check for a mistake
	if ((expected_offspring>0)&&
		(organisms.size()==0)) {
			//    std::cout<<"ERROR:  ATTEMPT TO REPRODUCE OUT OF EMPTY SPECIES"<<std::endl;
			return false;
		}

		poolsize=organisms.size()-1;

		thechamp=(*(organisms.begin()));

		//Create the designated number of offspring for the Species
		//one at a time
		for (count=0;count<expected_offspring;count++) {

			mut_struct_baby=false;
			mate_baby=false;

			outside=false;

			//Debug Trap
			if (expected_offspring>NEAT::pop_size) {
				//      std::cout<<"ALERT: EXPECTED OFFSPRING = "<<expected_offspring<<std::endl;
				//      cin>>pause;
			}

			//If we have a super_champ (Population champion), finish off some special clones
			if ((thechamp->super_champ_offspring) > 0) {
				mom=thechamp;
				new_genome=(mom->gnome)->duplicate(count);

				if ((thechamp->super_champ_offspring) == 1) {

				}

				//Most superchamp offspring will have their connection weights mutated only
				//The last offspring will be an exact duplicate of this super_champ
				//Note: Superchamp offspring only occur with stolen babies!
				//      Settings used for published experiments did not use this
				if ((thechamp->super_champ_offspring) > 1) {
					if ((randfloat()<0.8)||
						(NEAT::mutate_add_link_prob==0.0)) 
						//ABOVE LINE IS FOR:
						//Make sure no links get added when the system has link adding disabled
						new_genome->mutate_link_weights(mut_power,1.0,GAUSSIAN);
					else {
						//Sometimes we add a link to a superchamp
						net_analogue=new_genome->genesis(generation);
						new_genome->mutate_add_link(pop->innovations,pop->cur_innov_num,NEAT::newlink_tries);
						delete net_analogue;
						mut_struct_baby=true;
					}
				}

				baby=new Organism(0.0,new_genome,generation);

				if ((thechamp->super_champ_offspring) == 1) {
					if (thechamp->pop_champ) {
						//std::cout<<"The new org baby's genome is "<<baby->gnome<<std::endl;
						baby->pop_champ_child=true;
						baby->high_fit=mom->orig_fitness;
					}
				}

				thechamp->super_champ_offspring--;
			}
			//If we have a Species champion, just clone it 
			else if ((!champ_done)&&
				(expected_offspring>5)) {

					mom=thechamp; //Mom is the champ

					new_genome=(mom->gnome)->duplicate(count);

					baby=new Organism(0.0,new_genome,generation);  //Baby is just like mommy

					champ_done=true;

				}
				//First, decide whether to mate or mutate
				//If there is only one organism in the pool, then always mutate
			else if ((randfloat()<NEAT::mutate_only_prob)||
				poolsize== 0) {

					//Choose the random parent

					//RANDOM PARENT CHOOSER
					orgnum=randint(0,poolsize);
					curorg=organisms.begin();
					for(orgcount=0;orgcount<orgnum;orgcount++)
						++curorg;                       



					////Roulette Wheel
					//marble=randfloat()*total_fitness;
					//curorg=organisms.begin();
					//spin=(*curorg)->fitness;
					//while(spin<marble) {
					//++curorg;

					////Keep the wheel spinning
					//spin+=(*curorg)->fitness;
					//}
					////Finished roulette
					//

					mom=(*curorg);

					new_genome=(mom->gnome)->duplicate(count);

					//Do the mutation depending on probabilities of 
					//various mutations

					if (randfloat()<NEAT::mutate_add_node_prob) {
						//std::cout<<"mutate add node"<<std::endl;
						new_genome->mutate_add_node(pop->innovations,pop->cur_node_id,pop->cur_innov_num);
						mut_struct_baby=true;
					}
					else if (randfloat()<NEAT::mutate_add_link_prob) {
						//std::cout<<"mutate add link"<<std::endl;
						net_analogue=new_genome->genesis(generation);
						new_genome->mutate_add_link(pop->innovations,pop->cur_innov_num,NEAT::newlink_tries);
						delete net_analogue;
						mut_struct_baby=true;
					}
					//NOTE:  A link CANNOT be added directly after a node was added because the phenotype
					//       will not be appropriately altered to reflect the change
					else {
						//If we didn't do a structural mutation, we do the other kinds

						if (randfloat()<NEAT::mutate_random_trait_prob) {
							//std::cout<<"mutate random trait"<<std::endl;
							new_genome->mutate_random_trait();
						}
						if (randfloat()<NEAT::mutate_link_trait_prob) {
							//std::cout<<"mutate_link_trait"<<std::endl;
							new_genome->mutate_link_trait(1);
						}
						if (randfloat()<NEAT::mutate_node_trait_prob) {
							//std::cout<<"mutate_node_trait"<<std::endl;
							new_genome->mutate_node_trait(1);
						}
						if (randfloat()<NEAT::mutate_link_weights_prob) {
							//std::cout<<"mutate_link_weights"<<std::endl;
							new_genome->mutate_link_weights(mut_power,1.0,GAUSSIAN);
						}
						if (randfloat()<NEAT::mutate_toggle_enable_prob) {
							//std::cout<<"mutate toggle enable"<<std::endl;
							new_genome->mutate_toggle_enable(1);

						}
						if (randfloat()<NEAT::mutate_gene_reenable_prob) {
							//std::cout<<"mutate gene reenable"<<std::endl;
							new_genome->mutate_gene_reenable();
						}
					}

					baby=new Organism(0.0,new_genome,generation);

				}

				//Otherwise we should mate 
			else {

				//Choose the random mom
				orgnum=randint(0,poolsize);
				curorg=organisms.begin();
				for(orgcount=0;orgcount<orgnum;orgcount++)
					++curorg;


				////Roulette Wheel
				//marble=randfloat()*total_fitness;
				//curorg=organisms.begin();
				//spin=(*curorg)->fitness;
				//while(spin<marble) {
				//++curorg;

				////Keep the wheel spinning
				//spin+=(*curorg)->fitness;
				//}
				////Finished roulette
				//

				mom=(*curorg);         

				//Choose random dad

				if ((randfloat()>NEAT::interspecies_mate_rate)) {
					//Mate within Species

					orgnum=randint(0,poolsize);
					curorg=organisms.begin();
					for(orgcount=0;orgcount<orgnum;orgcount++)
						++curorg;


					////Use a roulette wheel
					//marble=randfloat()*total_fitness;
					//curorg=organisms.begin();
					//spin=(*curorg)->fitness;
					//while(spin<marble) {
					//++curorg;
					//}

					////Keep the wheel spinning
					//spin+=(*curorg)->fitness;
					//}
					////Finished roulette
					//

					dad=(*curorg);
				}
				else {

					//Mate outside Species  
					randspecies=this;

					//Select a random species
					giveup=0;  //Give up if you cant find a different Species
					while((randspecies==this)&&(giveup<5)) {

						//This old way just chose any old species
						//randspeciesnum=randint(0,(pop->species).size()-1);

						//Choose a random species tending towards better species
						randmult=gaussrand()/4;
						if (randmult>1.0) randmult=1.0;
						//This tends to select better species
						randspeciesnum=(int) floor((randmult*(sorted_species.size()-1.0))+0.5);
						cursp=(sorted_species.begin());
						for(spcount=0;spcount<randspeciesnum;spcount++)
							++cursp;
						randspecies=(*cursp);

						++giveup;
					}

					//OLD WAY: Choose a random dad from the random species
					//Select a random dad from the random Species
					//NOTE:  It is possible that a mating could take place
					//       here between the mom and a baby from the NEW
					//       generation in some other Species
					//orgnum=randint(0,(randspecies->organisms).size()-1);
					//curorg=(randspecies->organisms).begin();
					//for(orgcount=0;orgcount<orgnum;orgcount++)
					//  ++curorg;
					//dad=(*curorg);            

					//New way: Make dad be a champ from the random species
					dad=(*((randspecies->organisms).begin()));

					outside=true;	
				}

				//Perform mating based on probabilities of differrent mating types
				if (randfloat()<NEAT::mate_multipoint_prob) { 
					new_genome=(mom->gnome)->mate_multipoint(dad->gnome,count,mom->orig_fitness,dad->orig_fitness,outside);
				}
				else if (randfloat()<(NEAT::mate_multipoint_avg_prob/(NEAT::mate_multipoint_avg_prob+NEAT::mate_singlepoint_prob))) {
					new_genome=(mom->gnome)->mate_multipoint_avg(dad->gnome,count,mom->orig_fitness,dad->orig_fitness,outside);
				}
				else {
					new_genome=(mom->gnome)->mate_singlepoint(dad->gnome,count);
				}

				mate_baby=true;

				//Determine whether to mutate the baby's Genome
				//This is done randomly or if the mom and dad are the same organism
				if ((randfloat()>NEAT::mate_only_prob)||
					((dad->gnome)->genome_id==(mom->gnome)->genome_id)||
					(((dad->gnome)->compatibility(mom->gnome))==0.0))
				{

					//Do the mutation depending on probabilities of 
					//various mutations
					if (randfloat()<NEAT::mutate_add_node_prob) {
						new_genome->mutate_add_node(pop->innovations,pop->cur_node_id,pop->cur_innov_num);
						//  std::cout<<"mutate_add_node: "<<new_genome<<std::endl;
						mut_struct_baby=true;
					}
					else if (randfloat()<NEAT::mutate_add_link_prob) {
						net_analogue=new_genome->genesis(generation);
						new_genome->mutate_add_link(pop->innovations,pop->cur_innov_num,NEAT::newlink_tries);
						delete net_analogue;
						//std::cout<<"mutate_add_link: "<<new_genome<<std::endl;
						mut_struct_baby=true;
					}
					else {
						//Only do other mutations when not doing sturctural mutations

						if (randfloat()<NEAT::mutate_random_trait_prob) {
							new_genome->mutate_random_trait();
							//std::cout<<"..mutate random trait: "<<new_genome<<std::endl;
						}
						if (randfloat()<NEAT::mutate_link_trait_prob) {
							new_genome->mutate_link_trait(1);
							//std::cout<<"..mutate link trait: "<<new_genome<<std::endl;
						}
						if (randfloat()<NEAT::mutate_node_trait_prob) {
							new_genome->mutate_node_trait(1);
							//std::cout<<"mutate_node_trait: "<<new_genome<<std::endl;
						}
						if (randfloat()<NEAT::mutate_link_weights_prob) {
							new_genome->mutate_link_weights(mut_power,1.0,GAUSSIAN);
							//std::cout<<"mutate_link_weights: "<<new_genome<<std::endl;
						}
						if (randfloat()<NEAT::mutate_toggle_enable_prob) {
							new_genome->mutate_toggle_enable(1);
							//std::cout<<"mutate_toggle_enable: "<<new_genome<<std::endl;
						}
						if (randfloat()<NEAT::mutate_gene_reenable_prob) {
							new_genome->mutate_gene_reenable(); 
							//std::cout<<"mutate_gene_reenable: "<<new_genome<<std::endl;
						}
					}

					//Create the baby
					baby=new Organism(0.0,new_genome,generation);

				}
				else {
					//Create the baby without mutating first
					baby=new Organism(0.0,new_genome,generation);
				}

			}

			//Add the baby to its proper Species
			//If it doesn't fit a Species, create a new one

			baby->mut_struct_baby=mut_struct_baby;
			baby->mate_baby=mate_baby;

			curspecies=(pop->species).begin();
			if (curspecies==(pop->species).end()){
				//Create the first species
				newspecies=new Species(++(pop->last_species),true);
				(pop->species).push_back(newspecies);
				newspecies->add_Organism(baby);  //Add the baby
				baby->species=newspecies;  //Point the baby to its species
			} 
			else {
				comporg=(*curspecies)->first();
				found=false;
				while((curspecies!=(pop->species).end())&&
					(!found)) {	
						if (comporg==0) {
							//Keep searching for a matching species
							++curspecies;
							if (curspecies!=(pop->species).end())
								comporg=(*curspecies)->first();
						}
						else if (((baby->gnome)->compatibility(comporg->gnome))<NEAT::compat_threshold) {
							//Found compatible species, so add this organism to it
							(*curspecies)->add_Organism(baby);
							baby->species=(*curspecies);  //Point organism to its species
							found=true;  //Note the search is over
						}
						else {
							//Keep searching for a matching species
							++curspecies;
							if (curspecies!=(pop->species).end()) 
								comporg=(*curspecies)->first();
						}
					}

					//If we didn't find a match, create a new species
					if (found==false) {
					  newspecies=new Species(++(pop->last_species),true);
					  //std::std::cout<<"CREATING NEW SPECIES "<<pop->last_species<<std::std::endl;
					  (pop->species).push_back(newspecies);
					  newspecies->add_Organism(baby);  //Add the baby
					  baby->species=newspecies;  //Point baby to its species
					}


			} //end else 

		}



		return true;
}
예제 #2
0
	Organism *Species::reproduce_one(int generation, Population *pop,std::vector<Species*> &sorted_species) {
	//bool Species::reproduce(int generation, Population *pop,std::vector<Species*> &sorted_species) {
	int count=generation; //This will assign genome id's according to the generation
	std::vector<Organism*>::iterator curorg;


	std::vector<Organism*> elig_orgs; //This list contains the eligible organisms (KEN)

	int poolsize;  //The number of Organisms in the old generation

	int orgnum;  //Random variable
	int orgcount;
	Organism *mom = 0; //Parent Organisms
	Organism *dad = 0;
	Organism *baby;  //The new Organism

	Genome *new_genome=0;  //For holding baby's genes

	std::vector<Species*>::iterator curspecies;  //For adding baby
	Species *newspecies; //For babies in new Species
	Organism *comporg;  //For Species determination through comparison

	Species *randspecies;  //For mating outside the Species
	double randmult;
	int randspeciesnum;
	int spcount;  
	std::vector<Species*>::iterator cursp;

	Network *net_analogue;  //For adding link to test for recurrency
	int pause;

	bool outside;

	bool found;  //When a Species is found

	bool champ_done=false; //Flag the preservation of the champion  

	Organism *thechamp;

	int giveup; //For giving up finding a mate outside the species

	bool mut_struct_baby;
	bool mate_baby;

	//The weight mutation power is species specific depending on its age
	double mut_power=NEAT::weight_mut_power;

	//Roulette wheel variables
	double total_fitness=0.0;
	double marble;  //The marble will have a number between 0 and total_fitness
	double spin;  //Fitness total while the wheel is spinning


	//printf("In reproduce_one");

	//Check for a mistake
	if ((organisms.size()==0)) {
		//    cout<<"ERROR:  ATTEMPT TO REPRODUCE OUT OF EMPTY SPECIES"<<endl;
		return false;
	}

	rank(); //Make sure organisms are ordered by rank

	//ADDED CODE (Ken) 
	//Now transfer the list to elig_orgs without including the ones that are too young (Ken)
	for(curorg=organisms.begin();curorg!=organisms.end();++curorg) {
		if ((*curorg)->time_alive >= NEAT::time_alive_minimum)
			elig_orgs.push_back(*curorg);
	}

	//Now elig_orgs should be an ordered list of mature organisms
	//Special case: if it's empty, then just include all the organisms (age doesn't matter in this case) (Ken)
	if (elig_orgs.size()==0) {
			for(curorg=organisms.begin();curorg!=organisms.end();++curorg) {
					elig_orgs.push_back(*curorg);
		}		
	}

	//std::cout<<"Eligible orgs: "<<elig_orgs.size()<<std::endl;

	//Now elig_orgs is guaranteed to contain either an ordered list of mature orgs or all the orgs (Ken)
	//We may also want to check to see if we are getting pools of >1 organism (to make sure our survival_thresh is sensible) (Ken)

	//Only choose from among the top ranked orgs
	poolsize=(elig_orgs.size() - 1) * NEAT::survival_thresh;
	//poolsize=(organisms.size()-1)*.9;

	//Compute total fitness of species for a roulette wheel
	//Note: You don't get much advantage from a roulette here
	// because the size of a species is relatively small.
	// But you can use it by using the roulette code here
	for(curorg=elig_orgs.begin();curorg!=elig_orgs.end();++curorg) {
	  total_fitness+=(*curorg)->fitness;
	}

	//In reproducing only one offspring, the champ shouldn't matter  
	//thechamp=(*(organisms.begin()));

	//Create one offspring for the Species

	mut_struct_baby=false;
	mate_baby=false;

	outside=false;

	//First, decide whether to mate or mutate
	//If there is only one organism in the pool, then always mutate
	if ((randfloat()<NEAT::mutate_only_prob)||
		poolsize == 0) {

			//Choose the random parent

			//RANDOM PARENT CHOOSER
			orgnum=randint(0,poolsize);
			curorg=elig_orgs.begin();
			for(orgcount=0;orgcount<orgnum;orgcount++)
				++curorg;                       



			////Roulette Wheel
			//marble=randfloat()*total_fitness;
			//curorg=elig_orgs.begin();
			//spin=(*curorg)->fitness;
			//while(spin<marble) {
			//	++curorg;

				//Keep the wheel spinning
			//	spin+=(*curorg)->fitness;
			//}
			//Finished roulette
			

			mom=(*curorg);

			new_genome=(mom->gnome)->duplicate(count);

			//Do the mutation depending on probabilities of 
			//various mutations

			if (randfloat()<NEAT::mutate_add_node_prob) {
				//cout<<"mutate add node"<<endl;
				new_genome->mutate_add_node(pop->innovations,pop->cur_node_id,pop->cur_innov_num);
				mut_struct_baby=true;
			}
			else if (randfloat()<NEAT::mutate_add_link_prob) {
				//cout<<"mutate add link"<<endl;
				net_analogue=new_genome->genesis(generation);
				new_genome->mutate_add_link(pop->innovations,pop->cur_innov_num,NEAT::newlink_tries);
				delete net_analogue;
				mut_struct_baby=true;
			}
			//NOTE:  A link CANNOT be added directly after a node was added because the phenotype
			//       will not be appropriately altered to reflect the change
			else {
				//If we didn't do a structural mutation, we do the other kinds

				if (randfloat()<NEAT::mutate_random_trait_prob) {
					//cout<<"mutate random trait"<<endl;
					new_genome->mutate_random_trait();
				}
				if (randfloat()<NEAT::mutate_link_trait_prob) {
					//cout<<"mutate_link_trait"<<endl;
					new_genome->mutate_link_trait(1);
				}
				if (randfloat()<NEAT::mutate_node_trait_prob) {
					//cout<<"mutate_node_trait"<<endl;
					new_genome->mutate_node_trait(1);
					new_genome->mutate_node_parameters(NEAT::time_const_mut_power,NEAT::time_const_mut_prob,
						NEAT::bias_mut_power,NEAT::bias_mut_prob,NEAT::afunc_mut_prob);
				}
				if (randfloat()<NEAT::mutate_link_weights_prob) {
					//cout<<"mutate_link_weights"<<endl;
					new_genome->mutate_link_weights(mut_power,1.0,GAUSSIAN);
				}
				if (randfloat()<NEAT::mutate_toggle_enable_prob) {
					//cout<<"mutate toggle enable"<<endl;
					new_genome->mutate_toggle_enable(1);

				}
				if (randfloat()<NEAT::mutate_gene_reenable_prob) {
					//cout<<"mutate gene reenable"<<endl;
					new_genome->mutate_gene_reenable();
				}
			}

			baby=new Organism(0.0,new_genome,generation);

		}

		//Otherwise we should mate 
	else {

		//Choose the random mom
		orgnum=randint(0,poolsize);
		curorg=elig_orgs.begin();
		for(orgcount=0;orgcount<orgnum;orgcount++)
			++curorg;


		////Roulette Wheel
		//marble=randfloat()*total_fitness;
		//curorg=elig_orgs.begin();
		//spin=(*curorg)->fitness;
		//while(spin<marble) {
		//	++curorg;

			//Keep the wheel spinning
	  //	spin+=(*curorg)->fitness;
	  //}
		//Finished roulette
		

		mom=(*curorg);         

		//Choose random dad

		if ((randfloat()>NEAT::interspecies_mate_rate)) {
			//Mate within Species

			orgnum=randint(0,poolsize);
			curorg=elig_orgs.begin();
			for(orgcount=0;orgcount<orgnum;orgcount++)
				++curorg;


			////Use a roulette wheel
			//marble=randfloat()*total_fitness;
			//curorg=elig_orgs.begin();
			//spin=(*curorg)->fitness;
			//while(spin<marble) {
			//	++curorg;

			
				//Keep the wheel spinning
		  //	spin+=(*curorg)->fitness;
		  //}
			////Finished roulette
				

			dad=(*curorg);
		}
		else {

			//Mate outside Species  
			randspecies=this;

			//Select a random species
			giveup=0;  //Give up if you cant find a different Species
			while((randspecies==this)&&(giveup<5)) {

				//This old way just chose any old species
				//randspeciesnum=randint(0,(pop->species).size()-1);

				//Choose a random species tending towards better species
				randmult=gaussrand()/4;
				if (randmult>1.0) randmult=1.0;
				//This tends to select better species
                randspeciesnum=(int) floor((randmult*(sorted_species.size()-1.0))+0.5);
				cursp=(sorted_species.begin());
				for(spcount=0;spcount<randspeciesnum;spcount++)
					++cursp;
				randspecies=(*cursp);

				++giveup;
			}

			//OLD WAY: Choose a random dad from the random species
			//Select a random dad from the random Species
			//NOTE:  It is possible that a mating could take place
			//       here between the mom and a baby from the NEW
			//       generation in some other Species
			//orgnum=randint(0,(randspecies->organisms).size()-1);
			//curorg=(randspecies->organisms).begin();
			//for(orgcount=0;orgcount<orgnum;orgcount++)
			//  ++curorg;
			//dad=(*curorg);            

			//New way: Make dad be a champ from the random species
			dad=(*((randspecies->organisms).begin()));

			outside=true;
		}

		//Perform mating based on probabilities of differrent mating types
		if (randfloat()<NEAT::mate_multipoint_prob) { 
			new_genome=(mom->gnome)->mate_multipoint(dad->gnome,count,mom->orig_fitness,dad->orig_fitness,outside);
		}
		else if (randfloat()<(NEAT::mate_multipoint_avg_prob/(NEAT::mate_multipoint_avg_prob+NEAT::mate_singlepoint_prob))) {
			new_genome=(mom->gnome)->mate_multipoint_avg(dad->gnome,count,mom->orig_fitness,dad->orig_fitness,outside);
		}
		else {
			new_genome=(mom->gnome)->mate_singlepoint(dad->gnome,count);
		}

		mate_baby=true;

		//Determine whether to mutate the baby's Genome
		//This is done randomly or if the mom and dad are the same organism
		if ((randfloat()>NEAT::mate_only_prob)||
			((dad->gnome)->genome_id==(mom->gnome)->genome_id)||
			(((dad->gnome)->compatibility(mom->gnome))==0.0))
		{

			//Do the mutation depending on probabilities of 
			//various mutations
			if (randfloat()<NEAT::mutate_add_node_prob) {
				new_genome->mutate_add_node(pop->innovations,pop->cur_node_id,pop->cur_innov_num);
				//  cout<<"mutate_add_node: "<<new_genome<<endl;
				mut_struct_baby=true;
			}
			else if (randfloat()<NEAT::mutate_add_link_prob) {
				net_analogue=new_genome->genesis(generation);
				new_genome->mutate_add_link(pop->innovations,pop->cur_innov_num,NEAT::newlink_tries);
				delete net_analogue;
				//cout<<"mutate_add_link: "<<new_genome<<endl;
				mut_struct_baby=true;
			}
			else {
				//Only do other mutations when not doing strurctural mutations

				if (randfloat()<NEAT::mutate_random_trait_prob) {
					new_genome->mutate_random_trait();
					//cout<<"..mutate random trait: "<<new_genome<<endl;
				}
				if (randfloat()<NEAT::mutate_link_trait_prob) {
					new_genome->mutate_link_trait(1);
					//cout<<"..mutate link trait: "<<new_genome<<endl;
				}
				if (randfloat()<NEAT::mutate_node_trait_prob) {
                    new_genome->mutate_node_parameters(NEAT::time_const_mut_power,NEAT::time_const_mut_prob,
						NEAT::bias_mut_power,NEAT::bias_mut_prob,NEAT::afunc_mut_prob);
					new_genome->mutate_node_trait(1);
					//cout<<"mutate_node_trait: "<<new_genome<<endl;
				}
				if (randfloat()<NEAT::mutate_link_weights_prob) {
					new_genome->mutate_link_weights(mut_power,1.0,GAUSSIAN);
					//cout<<"mutate_link_weights: "<<new_genome<<endl;
				}
				if (randfloat()<NEAT::mutate_toggle_enable_prob) {
					new_genome->mutate_toggle_enable(1);
					//cout<<"mutate_toggle_enable: "<<new_genome<<endl;
				}
				if (randfloat()<NEAT::mutate_gene_reenable_prob) {
					new_genome->mutate_gene_reenable(); 
					//cout<<"mutate_gene_reenable: "<<new_genome<<endl;
				}
			}

			//Create the baby
			baby=new Organism(0.0,new_genome,generation);

		}
		else {
			//Create the baby without mutating first
			baby=new Organism(0.0,new_genome,generation);
		}

	}

	//Add the baby to its proper Species
	//If it doesn't fit a Species, create a new one

	baby->mut_struct_baby=mut_struct_baby;
	baby->mate_baby=mate_baby;

	curspecies=(pop->species).begin();
	if (curspecies==(pop->species).end()){
		//Create the first species
		newspecies=new Species(++(pop->last_species),true);
		(pop->species).push_back(newspecies);
		newspecies->add_Organism(baby);  //Add the baby
		baby->species=newspecies;  //Point the baby to its species
	} 
	else {
		comporg=(*curspecies)->first();
		found=false;


		// Testing out what happens when speciation is disabled
		//found = true;
		//(*curspecies)->add_Organism(baby);
		//baby->species = (*curspecies);


		while((curspecies!=(pop->species).end()) && (!found)) 
		{	
			if (comporg==0) {
				//Keep searching for a matching species
				++curspecies;
				if (curspecies!=(pop->species).end())
					comporg=(*curspecies)->first();
			}
			else if (((baby->gnome)->compatibility(comporg->gnome))<NEAT::compat_threshold) {
				//Found compatible species, so add this organism to it
				(*curspecies)->add_Organism(baby);
				baby->species=(*curspecies);  //Point organism to its species
				found=true;  //Note the search is over
			}
			else {
				//Keep searching for a matching species
				++curspecies;
				if (curspecies!=(pop->species).end()) 
					comporg=(*curspecies)->first();
			}
		}

		//If we didn't find a match, create a new species
		if (found==false) {
			newspecies=new Species(++(pop->last_species),true);
			(pop->species).push_back(newspecies);
			newspecies->add_Organism(baby);  //Add the baby
			baby->species=newspecies;  //Point baby to its species
		}

	} //end else     

	//Put the baby also in the master organism list
	(pop->organisms).push_back(baby);

	return baby; //Return a pointer to the baby
}