public void Evaluate(float[] scores) { // reset everything foreach (Species s in species) { s.ResetSpecies(new System.Random()); } scoreMap.Clear(); speciesMap.Clear(); nextGenGenomes.Clear(); highestScore = float.MinValue; fittestGenome = null; // place genomes into species foreach (Genome g in genomes) { bool foundSpecies = false; foreach (Species s in species) { if (Genome.CompatibilityDist(g, s.mascot, c1, c2, c3) < dt) { s.members.Add(g); speciesMap.Add(g, s); foundSpecies = true; break; } } if (!foundSpecies) // make new species { Species newSpecies = new Species(g); species.Add(newSpecies); speciesMap.Add(g, newSpecies); } } // remove dead species foreach (Species s in species.ToList()) { if (s.members.Count == 0) { species.Remove(s); } } if (species.Count > 11) { dt += 0.04f; ConsoleLogger.Log("dt: " + dt.ToString()); } else if (species.Count < 9) { dt -= 0.04f; ConsoleLogger.Log("dt: " + dt.ToString()); } ConsoleLogger.Log("No. species: " + species.Count.ToString()); // evaluate genomes and assign fitness foreach (Genome g in genomes) { Species s = speciesMap[g]; float score = scores.ToList()[genomes.IndexOf(g)]; float adjustedScore = score / speciesMap[g].members.Count; s.AddAdjustedFitness(adjustedScore); s.fitnessPop.Add(new FitnessGenome(g, adjustedScore)); scoreMap.Add(g, adjustedScore); if (score > highestScore) { highestScore = score; fittestGenome = g; } } // put best genomes from species into next generation foreach (Species s in species) { // sort genomes by fitness s.fitnessPop.Sort(FitnessGenomeComparator.CompareTo); s.fitnessPop.Reverse(); FitnessGenome fittestInSpecies = s.fitnessPop[0]; nextGenGenomes.Add(fittestInSpecies.genome); } Random rand = new Random(); // breed genomes while (nextGenGenomes.Count < populationSize) { Species s = GetRandomSpeciesBiasedAdjustedFitness(rand); Genome p1 = GetRandomGenomeBiasedAdjustedFitness(s, rand); if (rand.NextDouble() < _INTER_SPECIES_RATE) { s = GetRandomSpeciesBiasedAdjustedFitness(rand); } Genome p2 = GetRandomGenomeBiasedAdjustedFitness(s, rand); Genome child; if (scoreMap[p1] >= scoreMap[p2]) { child = Genome.Crossover(p1, p2); } else { child = Genome.Crossover(p2, p1); } if (rand.NextDouble() < _MUTATION_RATE) { child.ValueMutation(); } if (rand.NextDouble() < _ADD_CONONECTION_RATE) { child.AddConnectionMutation(); } if (rand.NextDouble() < _ADD_NODE_RATE) { child.AddNodeMutation(); } nextGenGenomes.Add(child); } genomes = nextGenGenomes; nextGenGenomes = new List <Genome>(); }