public bool IsCompatible(IGenome genome) { // Calculate compatibility distance between the two genomes GeneComparer comparer = new GeneComparer(); IEnumerable <IGene> matchingGenes = genome.Genes.Intersect(Genes, comparer); if (matchingGenes.Count() == 0) { return(false); } double averageWeightDifference = matchingGenes.Average(g => Math.Abs(g.Weight - Genes.First(gs => gs.Innovation == g.Innovation).Weight) ); IEnumerable <IGene> differingGenes = genome.Genes.Concat(Genes).Except(matchingGenes, comparer); // Disjoint/Excess genes IEnumerable <IGene> disjointGenes = differingGenes .Where(dg => dg.Innovation < matchingGenes.Max(g => g.Innovation)); int disjointCount = disjointGenes.ToList().Count(); int excessCount = differingGenes.Except(disjointGenes, comparer).ToList().Count(); IGenome largestGenome = Size() >= genome.Size() ? this : genome; int normalisation = largestGenome.Size() > GenomeParameters.GeneNormalisationThreshold ? largestGenome.Size() : 1; double compatibilityDistance = ((disjointCount * GenomeParameters.DisjointGeneCompatibilityFactor) / normalisation) + ((excessCount * GenomeParameters.ExcessGeneCompatibilityFactor) / normalisation) + (averageWeightDifference * GenomeParameters.AverageWeightDifferenceFactor); return(compatibilityDistance < GenomeParameters.CompatibilityDistanceThreshold); }
/// <summary> /// Returns the Last gene in the chromosome. /// Helper method that is typically used when Non-pheno type genes exist within the chromosome. /// </summary> /// <returns></returns> public Gene FirstGene() { return(Genes.First()); }
T GetGeneValue <T>(string name) where T : struct { return(Genes.First(g => g.Name == name).Value.As <T>()); }