Exemplo n.º 1
0
    private void CreateNextGeneration()
    {
        List <ClimberGenetics> newPopulation    = new List <ClimberGenetics>(PopulationSize);
        List <ClimberGenetics> sourcePopulation = new List <ClimberGenetics>(population);
        RouletteWheel          rouletteWheel;
        float averageFitness    = 0f;
        float highestGenFitness = 0f;

        // Calculate highest and average fitness
        foreach (ClimberGenetics genetics in population)
        {
            averageFitness   += genetics.FitnessScore;
            highestGenFitness = Mathf.Max(highestGenFitness, genetics.FitnessScore);
            highestFitness    = Mathf.Max(highestFitness, genetics.FitnessScore);
        }
        averageFitness /= population.Count;

        // Sort based on fitness (most to least fit)
        sourcePopulation.Sort((a, b) => { return(a.FitnessScore > b.FitnessScore ? -1 : 1); });

        // Before mating... KILL THE WEAK!@$
        for (int i = 0; i < NumToKill; i++)
        {
            ClimberGenetics deadbeat = sourcePopulation[sourcePopulation.Count - 1];

            Logger.Add("Killing individual with a score of: " + deadbeat.FitnessScore.ToString("0.00"));
            sourcePopulation.Remove(deadbeat);
        }

        rouletteWheel = new RouletteWheel(sourcePopulation);

        // Add survivors to new population
        newPopulation.AddRange(sourcePopulation);

        // Let's fuuuuu
        for (int i = 0; i < NumToKill; i++)
        {
            ClimberGenetics parentA = sourcePopulation[i];
            ClimberGenetics parentB = null;
            ClimberGenetics child   = null;

            // Choose a partner (making sure it's not self)
            while (parentB == null || parentB == parentA)
            {
                parentB = rouletteWheel.GetResult();
            }

            // Crossover genes from parents to child
            if (Random.Range(0f, 1f) < CrossoverRate)
            {
                int maxCrossoverIndex = Mathf.Min(parentA.Chromosome.Count, parentB.Chromosome.Count) - 1;
                int crossoverIndex    = Random.Range(0, maxCrossoverIndex + 1);
                int maxCount          = Mathf.Max(parentA.Chromosome.Count, parentB.Chromosome.Count);

                child = new ClimberGenetics();

                for (int j = 0; j < maxCount; j++)
                {
                    if (j < crossoverIndex)
                    {
                        child.Chromosome.Add(parentA.Chromosome[j]);
                    }
                    else
                    {
                        if (j < parentB.Chromosome.Count)
                        {
                            child.Chromosome.Add(parentB.Chromosome[j]);
                        }
                    }
                }
            }
            else
            {
                child = parentA.Copy();
            }

            // Mutate genes
            foreach (Gene gene in child.Chromosome)
            {
                if (Random.Range(0f, 1f) < MutationRate)
                {
                    MutateGene(child, gene);
                }
            }

            newPopulation.Add(child);
        }

        Logger.Add("Average fitness for generation " + currentGeneration + ": " + averageFitness.ToString("0.00"));
        Logger.Add("Highest fitness for generation " + currentGeneration + ": " + highestGenFitness.ToString("0.00"));
        Logger.Add("Highest all-time fitness: " + highestFitness.ToString("0.00"));

        currentGeneration++;
        population = newPopulation;
        Logger.Add("Created new genetic information for generation " + currentGeneration);
    }