/// <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); }
public GenomeComparisonInfo(Genome target1, Genome target2) { Target1 = target1; Target2 = target2; var genes1 = target1.Genes.OrderBy(x => x.InnovationNb).ToArray(); var genes2 = target2.Genes.OrderBy(x => x.InnovationNb).ToArray(); Disjoint = new Dictionary <Gene, Genome>(); Excess = new Dictionary <Gene, Genome>(); Matching = new List <Gene>(); var n = Mathf.Max(genes1.Length, genes2.Length); var comparer = new GeneComparer(); for (int i = 0; i < n; i++) { if (i < genes1.Length) { var geneFromParent2 = target2.GetGene(genes1[i]); if (geneFromParent2 != null) { if (Random.Range(0, 1f) <= 0.5f) { Matching.Add(genes1[i]); } else { Matching.Add(geneFromParent2); } } else { if (genes2.Length != 0 && genes1[i].InnovationNb <= genes2.Last().InnovationNb) { Disjoint.Add(genes1[i], target1); } else { Excess.Add(genes1[i], target1); } } } if (i < genes2.Length && !genes1.Contains(genes2[i], comparer)) { if (genes1.Length != 0 && genes2[i].InnovationNb <= genes1.Last().InnovationNb) { Disjoint.Add(genes2[i], target2); } else { Excess.Add(genes2[i], target2); } } } }