예제 #1
0
    public void Evaluate(float[] scores)
    {
        // reset everything
        foreach (Species s in species)
        {
            s.ResetSpecies(new System.Random());
        }

        scoreMap.Clear();
        speciesMap.Clear();
        nextGenGenomes.Clear();
        highestScore  = float.MinValue;
        fittestGenome = null;

        // place genomes into species
        foreach (Genome g in genomes)
        {
            bool foundSpecies = false;
            foreach (Species s in species)
            {
                if (Genome.CompatibilityDist(g, s.mascot, c1, c2, c3) < dt)
                {
                    s.members.Add(g);
                    speciesMap.Add(g, s);
                    foundSpecies = true;
                    break;
                }
            }
            if (!foundSpecies)   // make new species
            {
                Species newSpecies = new Species(g);
                species.Add(newSpecies);
                speciesMap.Add(g, newSpecies);
            }
        }



        // remove dead species
        foreach (Species s in species.ToList())
        {
            if (s.members.Count == 0)
            {
                species.Remove(s);
            }
        }

        if (species.Count > 11)
        {
            dt += 0.04f;
            ConsoleLogger.Log("dt: " + dt.ToString());
        }
        else if (species.Count < 9)
        {
            dt -= 0.04f;
            ConsoleLogger.Log("dt: " + dt.ToString());
        }

        ConsoleLogger.Log("No. species: " + species.Count.ToString());

        // evaluate genomes and assign fitness
        foreach (Genome g in genomes)
        {
            Species s = speciesMap[g];

            float score         = scores.ToList()[genomes.IndexOf(g)];
            float adjustedScore = score / speciesMap[g].members.Count;

            s.AddAdjustedFitness(adjustedScore);
            s.fitnessPop.Add(new FitnessGenome(g, adjustedScore));
            scoreMap.Add(g, adjustedScore);
            if (score > highestScore)
            {
                highestScore  = score;
                fittestGenome = g;
            }
        }

        // put best genomes from species into next generation
        foreach (Species s in species)
        {
            // sort genomes by fitness
            s.fitnessPop.Sort(FitnessGenomeComparator.CompareTo);
            s.fitnessPop.Reverse();

            FitnessGenome fittestInSpecies = s.fitnessPop[0];
            nextGenGenomes.Add(fittestInSpecies.genome);
        }

        Random rand = new Random();

        // breed genomes
        while (nextGenGenomes.Count < populationSize)
        {
            Species s = GetRandomSpeciesBiasedAdjustedFitness(rand);

            Genome p1 = GetRandomGenomeBiasedAdjustedFitness(s, rand);

            if (rand.NextDouble() < _INTER_SPECIES_RATE)
            {
                s = GetRandomSpeciesBiasedAdjustedFitness(rand);
            }

            Genome p2 = GetRandomGenomeBiasedAdjustedFitness(s, rand);

            Genome child;
            if (scoreMap[p1] >= scoreMap[p2])
            {
                child = Genome.Crossover(p1, p2);
            }
            else
            {
                child = Genome.Crossover(p2, p1);
            }
            if (rand.NextDouble() < _MUTATION_RATE)
            {
                child.ValueMutation();
            }
            if (rand.NextDouble() < _ADD_CONONECTION_RATE)
            {
                child.AddConnectionMutation();
            }
            if (rand.NextDouble() < _ADD_NODE_RATE)
            {
                child.AddNodeMutation();
            }
            nextGenGenomes.Add(child);
        }
        genomes        = nextGenGenomes;
        nextGenGenomes = new List <Genome>();
    }