/// <summary> /// Tell how different are 2 genomes. This is used in speciation. /// </summary> /// <returns>A normalized float.</returns> public static float GeneticDistance(NEATConfig config, Genome genome1, Genome genome2) { var distance = 0f; var comparisonInfo = new GenomeComparisonInfo(genome1, genome2); var genesCountInBiggest = Mathf.Max(genome1.Genes.Count, genome2.Genes.Count); var disjointDist = comparisonInfo.Disjoint.Count * config.speciesCompatibility.disjointImpact; var excessDist = comparisonInfo.Excess.Count * config.speciesCompatibility.excessImpact; distance += disjointDist / genesCountInBiggest; distance += excessDist / genesCountInBiggest; float totalWeightDif = 0; foreach (var gene in comparisonInfo.Matching) { var weight1 = Mathf.Abs(genome1.GetGene(gene).Weight); var weight2 = Mathf.Abs(genome2.GetGene(gene).Weight); var diff = Mathf.Abs(weight1 - weight2) / Mathf.Max(weight1, weight2); totalWeightDif += diff; } distance += totalWeightDif / comparisonInfo.Matching.Count * config.speciesCompatibility.weightMeanDifCoef; distance /= config.speciesCompatibility.TotalImpactSum; return(distance); }
/// <summary> /// Create a new offspring by combining the 2 parents' genes. /// The Matching genes are already randomly chosen from parent1 or p2. /// </summary> /// <returns>A fresh Genome (not mutated yet).</returns> public static Genome Crossover(NEATConfig config, Genome parent1, Genome parent2) { var fittestParent = (parent1.Fitness > parent2.Fitness) ? parent1 : parent2; var genesToInherit = new List <Gene>(fittestParent.Genes.Count); var comparisonInfo = new GenomeComparisonInfo(parent1, parent2); // The matching genes are chosen randomly from target1 or target2 genesToInherit.AddRange(comparisonInfo.Matching.Select(x => new Gene(x))); // Add the disjoint genes from the fittests. genesToInherit.AddRange(comparisonInfo.Disjoint.Where(x => x.Value == fittestParent) .Select(x => new Gene(x.Key))); // Add the excess genes from the fittests. genesToInherit.AddRange(comparisonInfo.Excess.Where(x => x.Value == fittestParent) .Select(x => new Gene(x.Key))); return(new Genome(fittestParent, genesToInherit)); }