Ejemplo n.º 1
0
        /// <summary>
        /// Get Genomes Fitness
        /// </summary>
        private void GetGenomesFitness()
        {
            foreach (Genome genome in _genomes)
            {
                // Get Species of the Genome
                Species species = _genomesSpecies[genome];

                float fitness         = EvaluateGenome(genome);
                float adjustedFitness = fitness / _genomesSpecies[genome].Genomes.Count;

                species.AddAdjustedFitness(adjustedFitness);
                genome.Fitness = adjustedFitness;
                species.Genomes.Add(new Genome(genome));
                if (fitness > BestFitness)
                {
                    BestFitness = fitness;
                    BestGenome  = genome;
                }
            }
        }
        // Runs one generation

        public void Evaluate()
        {
            // Reset everything for next generation
            foreach (Species s in species)
            {
                s.Reset(random);
            }
            fitnessMap.Clear();
            speciesMap.Clear();
            nextGenGenomes.Clear();
            highestFitness = float.MinValue;
            fittestGenome  = null;

            // Place genomes into species
            foreach (Genome g in genomes)
            {
                bool foundSpecies = false;
                foreach (Species s in species)
                {
                    if (Genome.CompatibilityDistance(g, s.mascot, C1, C2, C3) < DT)
                    { // compatibility distance is less than DT, so genome belongs to this species
                        s.members.Add(g);
                        speciesMap[g] = s;
                        foundSpecies  = true;
                        break;
                    }
                }
                if (!foundSpecies)
                { // if there is no appropiate species for genome, make a new one
                    Species newSpecies = new Species(g);
                    species.Add(newSpecies);
                    speciesMap[g] = newSpecies;
                }
            }

            // Remove unused species

            foreach (Species s in species)
            {
                if (!s.members.Any())
                {
                    species.Remove(s);
                }
            }


            // Evaluate genomes and assign score
            foreach (Genome g in genomes)
            {
                Species s = speciesMap[g];               // Get species of the genome

                float score         = evaluateGenome(g); // fitness of Genome
                float adjustedScore = score / speciesMap[g].members.Count;

                s.AddAdjustedFitness(adjustedScore);
                s.fitnessPop.Add(new FitnessGenome(g, adjustedScore));
                fitnessMap[g] = adjustedScore;
                if (score > highestFitness)
                {
                    highestFitness = score;
                    fittestGenome  = g;
                }
            }

            // put best genome from each species into next generation
            // species = species.OrderByDescending(s => s.fitnessPop).ToList();
            foreach (Species s in species)
            {
                FitnessGenome fittestInSpecies = s.fitnessPop.Max();
                nextGenGenomes.Add(fittestInSpecies.genome);
            }

            // Breed the rest of the genomes
            while (nextGenGenomes.Count < populationSize)
            { // replace removed genomes by randomly breeding
                Species s = getRandomSpeciesBiasedAjdustedFitness(random);

                Genome p1 = getRandomGenomeBiasedAdjustedFitness(s, random);
                Genome p2 = getRandomGenomeBiasedAdjustedFitness(s, random);

                Genome child = new Genome();
                if (fitnessMap[p1] >= fitnessMap[p2])
                {
                    child.Crossover(p1, p2);
                }
                else
                {
                    child.Crossover(p2, p1);
                }
                if (Random.Range(0f, 1f) < MUTATION_RATE)
                {
                    child.Mutation();
                }
                if (Random.Range(0f, 1f) < ADD_CONNECTION_RATE)
                {
                    //Debug.Log("Adding connection mutation...");
                    child.AddConnectionMutation(connectionInnovation, 10);
                }
                if (Random.Range(0f, 1f) < ADD_NODE_RATE)
                {
                    //Debug.Log("Adding node mutation...");
                    child.AddNodeMutation(connectionInnovation, nodeInnovation);
                }
                nextGenGenomes.Add(child);
            }

            genomes        = nextGenGenomes;
            nextGenGenomes = new List <Genome>();
        }