Ejemplo n.º 1
0
        /// <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);
        }
Ejemplo n.º 2
0
        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);
                    }
                }
            }
        }