/// <summary> /// Handles iterating a generation of the population. /// All evaluations must have been done by this point. /// </summary> /// <param name="rando">A random number generator.</param> public void Epoch(Random rando) { foreach (var spec in Species) { spec.SetChampions(); } SortSpeciesByChampionFitness(); Genome generationChampion = Species.Last().Fitness.Champion; if (generationChampion.Fitness.Score >= Fitness.ChampionScore) { GenerationPrime = Generation; } Fitness.GenerationalChampion = generationChampion; Dictionary <Species, int> ExpectedChildren = FindExpectedChildren(); foreach (var spec in Species) { int numberOfParents = (int)Math.Floor(spec.Size() * Const.SurvivalThresh + 1); spec.SortGenomesByFitness(); spec.Genomes.RemoveRange(0, spec.Size() - numberOfParents); } List <Genome> nextGenerationGenomes = new List <Genome>(); foreach (var specCountPair in ExpectedChildren) { nextGenerationGenomes.AddRange(specCountPair.Key.Reproduce(specCountPair.Value, GenerationalInnovations, Species, rando)); } ClearParentGeneration(); SpeciateNewGeneration(nextGenerationGenomes); RemoveDeadSpecies(); ResetSpeciesTemplates(); AgeSpecies(); Generation++; HistoricalInnovations.AddRange(GenerationalInnovations); GenerationalInnovations.Clear(); }
/// <summary> /// Creates an initial population. /// </summary> /// <param name="nodes">A list of NodeType-ActivationStyle pairing. The node Id will be the position in the list.</param> /// <param name="connections">A list of InNodeId-OutNodeId-Weight tuples.</param> /// <param name="populationSize">The size of the population to test.</param> /// <param name="rando">A random number generator for perturbing the weights.</param> public Population(List <Tuple <NodeType, ActivationStyle> > nodes, List <Tuple <int, int, double> > connections, int populationSize, Random rando) { TargetPopulationSize = populationSize; ValidateConstructorParameters(nodes.Count, connections); for (int i = 0; i < nodes.Count; i++) { NodePool.Add(new NodeInformation(nodes[i].Item1, nodes[i].Item2)); } List <Gene> startGenes = new List <Gene>(); foreach (var tupe in connections) { ConnectionInformation ci = new ConnectionInformation(tupe.Item1, tupe.Item2); startGenes.Add(new Gene(ci, ConnectionPool.Size(), tupe.Item3, false)); InnovationInformation info = new InnovationInformation(ci); info.NewConnectionDetails.ConnectionId = ConnectionPool.Size(); GenerationalInnovations.Add(info); ConnectionPool.Add(ci); } Genome adam = new Genome(startGenes); List <Genome> firstGen = new List <Genome>() { adam }; for (int i = 1; i < TargetPopulationSize; i++) { Genome copy = new Genome(adam); Mutation.MutateTryAllNonStructural(copy, rando); firstGen.Add(copy); } SpeciateNewGeneration(firstGen); }