Пример #1
0
 public static int CompareTo(FitnessGenome one, FitnessGenome two)
 {
     if (one.fitness > two.fitness)
     {
         return(1);
     }
     else if (one.fitness < two.fitness)
     {
         return(-1);
     }
     return(0);
 }
Пример #2
0
        // 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;

            int count1 = 0;
            int count2 = 0;

            // Place genomes into species
            foreach (Genome g in genomes)
            {
                count1++;
                bool foundSpecies = false;
                foreach (Species s in species)
                {
                    count2++;

                    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);
                    Debug.Log("New species created. Species amount: " + species.Count + ", g.Nodes.Count = " + g.Nodes.Count);
                    speciesMap[g] = newSpecies;
                }
            }

            // Remove unused species
            //using(IEnumerator<Species> sEnumerator = species.GetEnumerator())
            //{
            //    while (sEnumerator.MoveNext())
            //    {
            //        Species s = sEnumerator.Current;
            //        if (!s.members.Any())
            //        {
            //            sEnumerator
            //        }
            //    }
            //}
            foreach (Species s in species.ToList())
            {
                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)
            {
                float         bestFitness      = 0;
                FitnessGenome fittestInSpecies = new FitnessGenome();

                foreach (FitnessGenome fit in s.fitnessPop)
                {
                    if (fit.fitness > bestFitness)
                    {
                        fittestInSpecies = fit;
                        bestFitness      = fit.fitness;
                    }
                }

                if (fittestInSpecies.genome.Nodes.Count != 0)
                {
                    //    Debug.Log("OMG, g.Nodes.Count == 0 row 224");
                    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.NextDouble() < MUTATION_RATE)
                {
                    child.Mutation();
                }
                if (random.NextDouble() < ADD_CONNECTION_RATE)
                {
                    //Debug.Log("Adding connection mutation...");
                    child.AddConnectionMutation(connectionInnovation, 10);
                }
                if (random.NextDouble() < ADD_NODE_RATE)
                {
                    //Debug.Log("Adding node mutation...");
                    child.AddNodeMutation(nodeInnovation, connectionInnovation);
                }

                nextGenGenomes.Add(child);
            }
            genomes        = nextGenGenomes;
            nextGenGenomes = new List <Genome>();
        }
Пример #3
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>();
    }
Пример #4
0
        public void EvaluateGeneration()
        {
            _lastGenerationResults.Clear();
            _evaluatedGenomes.Clear();

            for (int i = 0; i < _genomes.Count; i++)
            {
                var genome        = _genomes[i];
                var fitnessGenome = new FitnessGenome()
                {
                    Fitness = EvaluateGenome(genome), Genome = genome
                };
                _evaluatedGenomes.Add(fitnessGenome);
            }

            //Sort Collections
            _evaluatedGenomes = _evaluatedGenomes.OrderByDescending(g => g.Fitness).ToList();

            _lastGenerationResults.AddRange(_evaluatedGenomes);

            //kill the 9/10 worst genomes
            var cutoffIndex = _evaluatedGenomes.Count / 10;

            _evaluatedGenomes = _evaluatedGenomes.Take(cutoffIndex).ToList();

            //find next generation population
            _nextGeneration.Clear();

            // save champ
            var champion = _evaluatedGenomes.First();

            FittestGenome = champion;
            _nextGeneration.Add(champion.Genome);

            while (_nextGeneration.Count() < _neatConfiguration.PopulationSize)
            {
                if (_random.NextDouble() > _neatConfiguration.ASexualReproductionRate)
                {
                    var           parent1 = _evaluatedGenomes[_random.Next(_evaluatedGenomes.Count)];
                    FitnessGenome parent2;
                    do
                    {
                        parent2 = _evaluatedGenomes[_random.Next(_evaluatedGenomes.Count)];
                    } while (parent2 == parent1);

                    Genome child;
                    if (parent1.Fitness > parent2.Fitness)
                    {
                        child = _crossFunctionStrategy.GenerateOffspring(parent1.Genome, parent2.Genome);
                    }
                    else
                    {
                        child = _crossFunctionStrategy.GenerateOffspring(parent2.Genome, parent1.Genome);
                    }

                    if (_random.NextDouble() < _neatConfiguration.MutationRate)
                    {
                        _weightMutation.Mutate(ref child);
                    }

                    if (_random.NextDouble() < _neatConfiguration.AddConnectionRate)
                    {
                        _addConnectionMutation.Mutate(ref child);
                    }

                    if (_random.NextDouble() < _neatConfiguration.AddNodeRate)
                    {
                        _addNodeMutation.Mutate(ref child);
                    }
                    _nextGeneration.Add(child);
                }
                else
                {
                    var parent = _evaluatedGenomes[_random.Next(_evaluatedGenomes.Count)];
                    var child  = parent.Genome.Copy();
                    _weightMutation.Mutate(ref child);
                    _nextGeneration.Add(child);
                }
            }

            //Transfer next generation to current generation
            _genomes.Clear();
            _genomes.AddRange(_nextGeneration);
        }