Пример #1
0
 public void Add(Genome genome)
 {
     Genomes.Add(genome);
 }
Пример #2
0
        private static ConnectionGene GetGeneFromFitterParent(NeatEvaluator evaluator, Genome fitParent, bool fitnessEqual, ConnectionGene connection, Genome genome)
        {
            ConnectionGene geneToTake = null;

            if (fitnessEqual)
            {
                if (evaluator.GetRandomFloat() < 0.5)
                {
                    geneToTake = connection.Copy(null);
                }
            }
            else
            {
                if (genome == fitParent)
                {
                    geneToTake = connection.Copy(null);
                }
            }

            return(geneToTake);
        }
Пример #3
0
        public Dictionary <Genome, Species> Selection(int population)
        {
            if (SpeciesItems.Count == 0)
            {
                throw new InvalidOperationException("No species found!?");
            }

            Dictionary <Genome, Species> nextGeneration = new Dictionary <Genome, Species>();

            float sumOfAllAdjustedFitnesses = SpeciesItems.Sum(x => x.CalcuateAdjustedFitnessSum());

            var speciesByFitness = SpeciesItems.OrderByDescending(x => x.AdjustedFitnessSum).ToList();
            int rank             = 1;

            float totalSum = sumOfAllAdjustedFitnesses;
            int   offspringToDistribute = population;

            foreach (var species in speciesByFitness)
            {
                species.SetRank(rank);
                rank++;

                var   fitnessSum          = species.AdjustedFitnessSum;
                float offspringPerSpecies = fitnessSum / totalSum;
                totalSum -= fitnessSum;
                int offspring = (int)Math.Ceiling(offspringToDistribute * offspringPerSpecies);

                if (offspring > offspringToDistribute)
                {
                    offspring = offspringToDistribute;
                }

                int offspringToUse    = offspring;
                int offspringAssigned = 0;

                var champ = species.Champion.Copy();
                if (champ != null && species.Genomes.Count > Evaluator.NeatConfig.ChampCopyThreshold)
                {
                    nextGeneration.Add(champ, species);
                    offspringAssigned++;
                    offspringToUse--;
                }

                if (Evaluator.NeatConfig.UseStagnation)
                {
                    float stagnationEqualTolerance = 0.001f;
                    float difference = species.AdjustedFitnessSum - species.LastFitness;

                    if (difference < stagnationEqualTolerance)
                    {
                        species.StagnationCounter++;
                        if (species.StagnationCounter > Evaluator.NeatConfig.StagnationThreshold)
                        {
                            offspringToUse    = 0;
                            species.Stagnated = true;
                        }
                    }
                    else
                    {
                        species.StagnationCounter = 0;
                    }
                }

                species.LastFitness = species.AdjustedFitnessSum;

                if (offspringToUse <= 0)
                {
                    continue; // skip this species, because it received no population at all
                }

                int offspringToMate  = (int)Math.Floor(offspringToUse * Evaluator.NeatConfig.CrossoverOffspringRate);
                int offspringToClone = offspringToUse - offspringToMate;

                var selection = species.Selection();
                var adjustedFitnessGenomesLookup = selection.ToDictionary(x => x, x => (x.Fitness / species.Genomes.Count));

                for (int i = 0; i < offspringToMate; i++)
                {
                    // only mate interspecies if the rate matches and
                    var doInterspeciesCrossover =
                        speciesByFitness.Count > 1 && Evaluator.GetRandomFloat() < Evaluator.NeatConfig.InterspeciesMatingRate;

                    if (doInterspeciesCrossover)
                    {
                        var p1 = GetRandomGenomeBiasedAdjustedFitness(adjustedFitnessGenomesLookup);

                        var intermateSpeciesList = speciesByFitness.Where(x => x != species).ToList();

                        var intermateSpeciesRndIndex = Evaluator.Random.Next(0, intermateSpeciesList.Count);
                        var intermateSpecies         = intermateSpeciesList[intermateSpeciesRndIndex];

                        if (intermateSpecies.Genomes.Count > 0)
                        {
                            var intermateGenomeIndex = Evaluator.Random.Next(0, intermateSpecies.Genomes.Count);
                            var intermateGenome      = intermateSpecies.Genomes.Items[intermateGenomeIndex];

                            var child = Genome.Crossover(Evaluator, p1, intermateGenome);
                            child.Mutate();
                            nextGeneration.Add(child, species);
                            offspringAssigned++;
                        }
                        else
                        {
                            doInterspeciesCrossover = false; // fallback when somehow there were no genomes in the other species
                        }
                    }

                    if (!doInterspeciesCrossover)
                    {
                        var p1 = GetRandomGenomeBiasedAdjustedFitness(adjustedFitnessGenomesLookup);
                        var p2 = GetRandomGenomeBiasedAdjustedFitness(adjustedFitnessGenomesLookup);

                        var child = Genome.Crossover(Evaluator, p1, p2);
                        child.Mutate();
                        nextGeneration.Add(child, species);
                        offspringAssigned++;
                    }
                }

                for (int i = 0; i < offspringToClone; i++)
                {
                    var p1    = GetRandomGenomeBiasedAdjustedFitness(adjustedFitnessGenomesLookup);
                    var clone = p1.Copy();
                    clone.Mutate();
                    nextGeneration.Add(clone, species);
                    offspringAssigned++;
                }
                offspringToDistribute -= offspringAssigned;
            }

            return(nextGeneration);
        }