/// <summary>
        /// Generates the next generation of the population.
        /// </summary>
        public void NextGeneration()
        {
            var avgDamage       = Genomes.Average(g => g.DamageDealt);
            var avgSurvivalTime = Genomes.Average(g => g.SurvivalTime);

            // make a copy of the genomes and sort by fitness (high to low)
            var orderedGenomes = Genomes.ToList();

            orderedGenomes.Sort((a, b) =>
            {
                var aFitness = a.GetFitness(avgDamage, avgSurvivalTime);
                var bFitness = b.GetFitness(avgDamage, avgSurvivalTime);

                if (aFitness > bFitness)
                {
                    return(1);
                }
                if (aFitness < bFitness)
                {
                    return(-1);
                }

                return(0);
            });

            // trim out the worst genomes
            var toRemove = (int)Math.Floor(ReplacementPercent * Size);

            orderedGenomes.RemoveRange(Size - toRemove, toRemove);

            for (var i = 0; i < Size; i++)
            {
                if (i < NumClones)
                {
                    m_genomes[i]                 = orderedGenomes[i];
                    orderedGenomes[i].Id         = i;
                    orderedGenomes[i].GenomeType = GenomeType.Clone;
                    orderedGenomes[i].ResetStats();
                }
                else
                {
                    var genome = DoCrossover(orderedGenomes);
                    genome.Id = i;

                    if (Random.NextDouble() < MutationRate)
                    {
                        genome.Mutate();
                    }

                    m_genomes[i] = genome;
                }
            }

            Generation++;
        }
Example #2
0
        public void Evaluate(Func <IGenome, double> getFitness)
        {
            // Genome Fitness
            Genomes.ForEach(g => g.Fitness = getFitness(g));

            // Species Fitness
            Species.ForEach(s => s.SetFitness());

            // Population Fitness
            Fitness = Genomes.Sum(g => g.Fitness);

            AverageFitness = Genomes.Average(g => g.Fitness);
            AverageFitness = AverageFitness == 0 ? 1 : AverageFitness;

            // Genome Expected Offspring
            Genomes.ForEach(g => g.ExpectedOffspring = g.Fitness / AverageFitness);

            // Species Expected Offspring
            Species.ForEach(s => s.SetExpectedOffspring());
        }
Example #3
0
        public void SetFitness()
        {
            int ageDebt = (Age - LastImprovementAge + 1) - SpeciesParameters.DropOffAge;

            ageDebt = ageDebt == 0 ? 1 : ageDebt;

            Genomes.ForEach(g =>
            {
                if (ageDebt >= 1)
                {
                    g.Fitness *= SpeciesParameters.DropOffAgePenaltyFactor;
                }

                if (Age <= 10)
                {
                    g.Fitness *= SpeciesParameters.AgeSignificance;
                }

                if (g.Fitness < 0)
                {
                    g.Fitness = 0.0001;
                }

                g.Fitness /= Genomes.Count;
            });

            Fitness = Genomes.Any() ? Genomes.Average(g => g.Fitness) : 0;

            if (Fitness > MaxFitness)
            {
                MaxFitness         = Fitness;
                LastImprovementAge = 0;
            }
            else
            {
                LastImprovementAge++;
            }
        }