コード例 #1
0
        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);
        }