Пример #1
0
        /// <summary>
        /// Main constructor for evolution. Requires a configuration instance
        /// </summary>
        /// <param name="config"></param>
        public Evolution(EvolutionConfig config)
        {
            // Setup new lists
            genomes = new List<Genome>();
            species = new List<Species>();

            // Reset basic variables
            evaluationIndex = 0;
            speciesFitnessSum = 0;
            generationNumber = 0;
            topScore = 0;

            // Set the configuration
            evoConfig = config;

            // Create new random genomes
            for (int i = 0; i < config.PopulationSize; i++)
                genomes.Add(new Genome(config));

            // Mutate each genenome, add add them to a species
            foreach (Genome g in genomes) {
                g.Mutate();
                AddGenomeToSpecies(g);
            }

            // Setup netwrok
            evaluationNetwork = new NeuralNetwork(genomes[0]);
        }
Пример #2
0
        /// <summary>
        /// After the network has been used, we need to evaluate the network, assign a fitness score and move on.
        /// </summary>
        /// <param name="fitnessScore"></param>
        public void EvaluateNetwork(double fitnessScore)
        {
            // Update the fitness of this genome
            genomes[evaluationIndex++].Fitness = fitnessScore;

            // When the last genome was evaluated, setup the next generation
            if (evaluationIndex >= genomes.Count()) {
                NextGeneration();
                onGenerationEnded(EventArgs.Empty);
            }
            else // Setup next network
                evaluationNetwork = new NeuralNetwork(genomes[evaluationIndex]);
        }
Пример #3
0
        /// <summary>
        /// This constructor creates a new generation from a previous generation
        /// </summary>
        /// <param name="evoConfig"></param>
        /// <param name="previousGeneration"></param>
        public void NextGeneration()
        {
            // Clear the list of genomes (we want to update them)
            genomes.Clear();

            List<Species> nextSpecies = new List<Species>(species);

            foreach (Species s in species) {
                // 'Prune' the species
                s.KeepTopHalf();

                // Remove old 'dead' species that have not made any progress in a while
                s.UpdateStaleness();
                if (s.Staleness >= evoConfig.StaleSpecies && s.TopFitness < species.Max().TopFitness)
                    nextSpecies.Remove(s);
            }

            // Update species
            species = nextSpecies;
            nextSpecies = new List<Species>(species);

            UpdateSpeciesFitnessSum();

            // Remove species that are not going to be bred because they have low fitness sums
            foreach (Species s in species) {
                if (evoConfig.PopulationSize * s.AverageFitness / speciesFitnessSum < 1 && s.TopFitness < species.Max().TopFitness)
                    nextSpecies.Remove(s);
            }

            // Update species
            species = nextSpecies;

            UpdateSpeciesFitnessSum();

            // Breed new children
            List<Genome> children = new List<Genome>();
            foreach (Species s in species) {
                // Estimate how many children should be bred per species
                int breedCount = (int) (evoConfig.PopulationSize * s.AverageFitness / speciesFitnessSum);

                // Make new children
                for (int i = 0; i < breedCount; i++)
                    children.Add(Genome.BreedChild(evoConfig, s));

                // Keep the best from each species
                s.KeepTop(1);

                // Add them to the list of genomes
                foreach(Genome g in s.genomes)
                    genomes.Add(g);
            }

            // Find the top score
            topScore = genomes.Max(g => g.Fitness);

            // Since we only estimated how many children should be bred per species, we can't be sure we actually fit the number required (decimals)
            // So we need to add more children by randomly selecting species and breeding them again
            while (children.Count < evoConfig.PopulationSize)
                children.Add(Genome.BreedChild(evoConfig,
                    species.ElementAt(
                    evoConfig.rng.Next(species.Count()))));

            // Assign each child a species (most likely within its same species, but sometimes they get adopted)
            foreach (Genome g in children) {
                AddGenomeToSpecies(g);

                // Add to global genome list
                genomes.Add(g);
            }

            // Reset evaluation index;
            evaluationIndex = 0;

            // Setup netwrok
            evaluationNetwork = new NeuralNetwork(genomes[0]);

            // Increment generation counter
            generationNumber++;
        }