public void NextGeneration(Species species, int numChildren) { if (numChildren == 0) { return; //hacky.... } //replace old list with new one var children = new List <Genome>(); var parents = new List <Genome>(); int parentCount = (int)(species.Genomes.Count * Config.survivalCutoff); //ensure at least one parent parentCount = Math.Max(parentCount, 1); //only add a proportion of the population to parent pool based on survival cutoff for (int i = 0; i < parentCount; i++) { parents.Add(species.Genomes[i]); } int asexualCount = (int)(numChildren * Config.rateAsexual); if (parentCount == 1) { asexualCount = numChildren; } //pick random parents and cross them to get child for (int i = 0; i < (numChildren - asexualCount); i++) { //don't cross the same parents var parent1 = parents[Config.globalRandom.Next(0, parents.Count)]; var parent2 = parents[Config.globalRandom.Next(0, parents.Count)]; var parentFittest = parent1.Fitness >= parent2.Fitness ? parent1 : parent2; //var parentWeaker = parent1.Fitness < parent2.Fitness ? parent1 : parent2; //create child topology from fitter parent var child = parentFittest.Clone(); //randomly crossover any shared connections child.CrossOver(parent1, parent2); children.Add(child); } //asexual reproduction for (int i = 0; i < asexualCount; i++) { //add asexual in order of parents var parent1 = parents[Config.globalRandom.Next(0, parents.Count)]; children.Add(parent1.Clone()); } //mutate all the children genomes foreach (var child in children) { //mutate individual connection weights child.MutateConnectionWeights(); //mutate add new connection var r1 = Config.globalRandom.NextDouble(); if (r1 < Config.rateAddConnection) { child.MutateAddConnection(); } var r2 = Config.globalRandom.NextDouble(); if (r2 < Config.rateAddNode) { child.MutateAddNode(this); } //if (r2 < 0.2) //{ // child.MutateNodeType(); //} //if (r2 < 0.02) //{ // child.MutateRemoveNode(); //} } //elitism if (species.Genomes.Count > 5) { children[Config.globalRandom.Next(0, children.Count)] = parents[0].Clone(); } species.Genomes = children; Genomes.AddRange(children); }