Ejemplo n.º 1
0
        public void TestSpecie()
        {
            var specie = new Specie(13, protoGenotype, 0, 0, 0.0f);

            for (int i = 0; i < 100; i++)
            {
                var gt = Genotype.FromPrototype(protoGenotype);
                var pt = new Phenotype(gt);
                specie.Add(pt);
            }

            foreach (var pt in specie)
            {
                pt.AdjustedFitness = 1.0f / (float)specie.Count;
            }

            Assert.AreEqual(0.0f, specie.MeanFitness, 0.001f);
            Assert.AreEqual(0.01f, specie.MeanAdjustedFitness, 0.001f);
            Assert.AreEqual(100, specie.Count);
        }
Ejemplo n.º 2
0
        public Specie[] Speciate(Specie[] species, Phenotype[] phenotypes)
        {
            // Begin new species
            var speciesListNext = species.Select(sp => {
                if (sp.BestAdjustedFitness >= sp.PastBestAdjustedFitness)
                {
                    return(new Specie(sp.SpeciesId, sp.Representative, sp.Age + 1,
                                      sp.Age, sp.BestAdjustedFitness));
                }
                else
                {
                    return(new Specie(sp.SpeciesId, sp.Representative, sp.Age + 1,
                                      sp.BestAge, sp.PastBestAdjustedFitness));
                }
            }).ToList();

            // Place genotypes
            foreach (var phenotype in phenotypes)
            {
                bool foundSpecies = false;

                foreach (var specie in speciesListNext)
                {
                    // Check if the phenotype belong to this species
                    var distance = distanceMetric.MeasureDistance(phenotype.Genotype, specie.Representative);
                    if (distance <= distanceThreshold)
                    {
                        specie.Add(phenotype);
                        foundSpecies = true;
                        break;
                    }
                }

                // Create a new species for the phenotype if necessary
                if (!foundSpecies)
                {
                    var spNext = new Specie(nextSpeciesId, phenotype.Genotype, 0, 0, 0.0f);
                    nextSpeciesId++;

                    spNext.Add(phenotype);
                    speciesListNext.Add(spNext);
                }
            }

            // Adjust threshold to accomodate the correct number of species
            if (speciesListNext.Count < desiredSpeciesCount)      // Too few
            {
                distanceThreshold -= distanceThresholdAdjustment; // Decrease threshold
            }
            else if (speciesListNext.Count > desiredSpeciesCount) // To many
            {
                distanceThreshold += distanceThresholdAdjustment; // Increase threshold
            }

            // Prune empty species
            var dead        = speciesListNext.Where(sp => sp.Count == 0);
            var speciesNext = speciesListNext.Except(dead);

            // Adjust each species' phenotypes' fitness
            foreach (var specie in speciesNext)
            {
                foreach (var phenotype in specie)
                {
                    var adjustedFitness = phenotype.Fitness;

                    var stagnation = specie.Age - specie.BestAge;
                    if (stagnation >= 10 && stagnation < 100)
                    {
                        // age: 10, penalty = 0.9x
                        // age: 25, penalty = 0.75x
                        // age: 50, penalty = 0.5x
                        // age: 75, penalty = 0.25x
                        // age: 90, penalty = 0.1x
                        adjustedFitness *= 1.0f - (stagnation / 100.0f); // Up to 100% penalty
                    }

                    if (specie.Age < 10)
                    {
                        // age: 0, reward = 2x
                        // age: 2, reward = 1.8x
                        // age: 5, reward = 1.5x
                        // age: 8, reward = 1.2x
                        // age: 10, reward = 1x
                        adjustedFitness *= 1.0f + (1.0f - (specie.Age / 10.0f)); // Up to 100% bonus
                    }

                    adjustedFitness /= (float)specie.Count;

                    phenotype.AdjustedFitness = Mathf.Max(adjustedFitness, 0.001f);
                }
            }

            return(speciesNext.OrderByDescending(sp => sp.BestAdjustedFitness)
                   .ToArray());
        }