Beispiel #1
0
            public ReproduceAndReplace_Node(ScoredDistribution <Organism> scoredDistribution_organisms, Species new_species)
            {
                this.scoredDistribution_organisms = scoredDistribution_organisms;

                this.new_species = new_species;
            }
Beispiel #2
0
        /// <summary>
        /// Performs speciation, adjusting fitness sums, culling, crossover, and mutation, to generate the next generation of Neural Networks
        /// </summary>
        public void Select()
        {
            speciesList = new List <Species>();
            foreach (NeuralNetwork NN in Networks)
            {
                bool foundSpecies = false;
                foreach (Species species in speciesList)
                {
                    if (NeuralNetwork.EvolutionaryDistance(species.networks.ElementAt(0), NN, innovationNumbers) < SpeciatingThreshold)
                    {
                        species.networks.Add(NN);
                        foundSpecies = true;
                        break;
                    }
                }
                if (!foundSpecies)
                {
                    speciesList.Add(new Species(NN));
                }
            }

            //Console.WriteLine("speciesList Count after speciating: " + speciesList.Count);
            //Console.WriteLine("Pop Consistency: " + isConsistent());

            foreach (Species species in speciesList)
            {
                species.networks.Sort((NN1, NN2) => NN2.Fitness.CompareTo(NN1.Fitness));
                int kill  = (int)(Math.Ceiling(species.networks.Count() * killRate));
                int total = species.networks.Count();
                for (int i = species.networks.Count() - 1; i > total - 1 - kill; i--)
                {
                    species.networks.RemoveAt(i);
                }

                for (int i = 0; i < species.networks.Count(); i++)
                {
                    species.adjustedFitnessSum += species.networks.ElementAt(i).Fitness / (species.networks.Count);
                }
            }

            speciesList.RemoveAll(x => x.networks.Count < 3);

            //Console.WriteLine("speciesList Count after killing: " + speciesList.Count);
            //Console.WriteLine("Pop Consistency: " + isConsistent());

            int numSelectionBreed = (int)(.75 * Size);

            speciesList.Sort((species1, species2) => species2.adjustedFitnessSum.CompareTo(species1.adjustedFitnessSum));

            double sharedFitnessTotal = 0;

            for (int i = 0; i < speciesList.Count / 3; i++)
            {
                Species species = speciesList.ElementAt(i);
                sharedFitnessTotal += species.adjustedFitnessSum;
            }

            //Console.WriteLine("speciesList Count after adjusting fitness sums: " + speciesList.Count);
            //Console.WriteLine("Pop Consistency: " + isConsistent());

            List <NeuralNetwork> childrenNetworks = new List <NeuralNetwork>();
            Random rand = new Random();

            for (int i = 0; i < speciesList.Count / 3; i++)
            {
                Species species = speciesList.ElementAt(i);
                for (int j = 0; j < numSelectionBreed * (species.adjustedFitnessSum / sharedFitnessTotal); j++)
                {
                    //Console.WriteLine("Pop Consistency: " + isConsistent());
                    NeuralNetwork NN1   = species.networks.ElementAt(rand.Next(species.networks.Count));
                    NeuralNetwork NN2   = species.networks.ElementAt(rand.Next(species.networks.Count));
                    NeuralNetwork Child = NeuralNetwork.Crossover(NN1, NN2, innovationNumbers);
                    Child.RandomMutation();
                    //Child.DisplayOutputConnections();
                    childrenNetworks.Add(Child);
                    //Console.WriteLine("Pop Consistency: " + isConsistent());
                    //Console.WriteLine();
                }
            }

            //Console.WriteLine();
            //Console.WriteLine("speciesList Count after selection breeding: "+ speciesList.Count);
            //Console.WriteLine("Pop Consistency: " + isConsistent());
            //Console.WriteLine();

            Networks.Sort((NN1, NN2) => NN2.Fitness.CompareTo(NN1.Fitness));
            for (int i = 0; i < 5; i++)
            {
                childrenNetworks.Add(Networks.ElementAt(i));
            }

            int numRandomBreed = Networks.Count - childrenNetworks.Count;

            for (int i = 0; i < numRandomBreed; i++)
            {
                Species randSpecies = speciesList[rand.Next(speciesList.Count)];

                NeuralNetwork randNN1 = randSpecies.networks[rand.Next(randSpecies.networks.Count)];
                NeuralNetwork randNN2 = randSpecies.networks[rand.Next(randSpecies.networks.Count)];
                NeuralNetwork child   = NeuralNetwork.Crossover(randNN1, randNN2, innovationNumbers);
                child.RandomMutation();
                //child.DisplayOutputConnections();
                childrenNetworks.Add(child);
            }

            //Console.WriteLine();
            //Console.WriteLine("speciesList Count after random breeding: " + speciesList.Count);
            //Console.WriteLine("Pop Consistency: " + isConsistent());
            //Console.WriteLine();

            Networks = new List <NeuralNetwork>(childrenNetworks);

            //Console.WriteLine("total child networks after selection: " + childrenNetworks.Count);
            //Console.WriteLine("Pop Consistency: " + isConsistent());
        }
Beispiel #3
0
        /// <summary>
        /// Reproduces the surviving species based on their fitness scores. Chooses the organisms in the species to mate based on fitness scores as well. Replaces the previous generation
        /// with the newly created organisms. Removes extinct species if necessary. Adjusts compatibility distance after replacement.
        /// See <see cref="NEAT.NEATClient.Evolve"/> before using!
        /// </summary>
        /// <remarks>
        /// Decides the amount of offspring (nk) each species (k) should be allotted via the following equation:
        /// <para/>
        /// nk = P * (Fk / Ft)
        /// <para/>
        /// Where:
        /// <list type="bullet">
        /// <item>k: The species.</item>
        /// <item>nk: The number of new organisms for species k in the next generation.</item>
        /// <item>P: The desired new population count.</item>
        /// <item>Fk: The average fitness score of the species.</item>
        /// <item>Ft: The sum of all fitness score averages of every species.</item>
        /// </list>
        /// </remarks>
        public void ReproduceAndReplace()
        {
            double total_speciesFitness = Species.Sum(x => x.AverageFitnessScore);


            Dictionary <Species, ReproduceAndReplace_Node> stored_distributionsSpecies = new Dictionary <Species, ReproduceAndReplace_Node>(Species.Count);


            List <Organism> next_generation = new List <Organism>(NumOrganisms);  //All of the new organisms.

            HashSet <Species> next_species = new HashSet <Species>(Species.Count);


            #region Reproduction

            foreach (Species species in Species)
            {
                //Calculate the number of organisms every species will have:
                int num_alloted_offspring = (int)(NumOrganisms * (species.AverageFitnessScore / total_speciesFitness));


                //Prepare new species for placement:
                Species creation_species = new Species();

                next_species.Add(creation_species);


                //Prepare ScoredDistribution for selecting organisms to mate:
                ScoredDistribution <Organism> internal_organisms = new ScoredDistribution <Organism>(species.Size, Pedigree.Random);

                foreach (Organism organism in species)
                {
                    internal_organisms.Add(organism, organism.FitnessScore);
                }

                stored_distributionsSpecies.Add(species, new ReproduceAndReplace_Node(internal_organisms, creation_species));


                //Actaully mate the organisms:
                for (int i = 0; i < num_alloted_offspring; ++i)
                {
                    Organism random_organism_1 = internal_organisms.ChooseValue();

                    Organism random_organism_2 = internal_organisms.ChooseValue(random_organism_1); //We don't want any self-replication...

                    if (random_organism_2 == null)
                    {
                        random_organism_2 = random_organism_1;  //Unless that's the only option ;) Only happens when the organism is the only one in the species.
                    }


                    Organism baby = new Organism(random_organism_1.Genome.Crossover(random_organism_1.FitnessScore, random_organism_2.Genome, random_organism_2.FitnessScore,
                                                                                    Pedigree.Random));

                    next_generation.Add(baby);

                    creation_species.AddOrganism(baby);
                }
            }


            while (next_generation.Count < NumOrganisms)   //We need more organisms, give it to some random species. Super rare that this doesn't happen.
            {
                ReproduceAndReplace_Node chosen_last_node = stored_distributionsSpecies[Species.RandomValue(Pedigree.Random)];


                ScoredDistribution <Organism> last_round_distribution = chosen_last_node.scoredDistribution_organisms;

                Species last_round_species = chosen_last_node.new_species;


                Organism random_organism_1 = last_round_distribution.ChooseValue();

                Organism random_organism_2 = last_round_distribution.ChooseValue(random_organism_1); //We don't want any self-replication...

                if (random_organism_2 == null)
                {
                    random_organism_2 = random_organism_1;  //Unless that's the only option ;) Only happens when the organism is the only one in the species.
                }


                Organism baby = new Organism(random_organism_1.Genome.Crossover(random_organism_1.FitnessScore, random_organism_2.Genome, random_organism_2.FitnessScore,
                                                                                Pedigree.Random));

                next_generation.Add(baby);

                last_round_species.AddOrganism(baby);
            }

            #endregion Reproduction


            #region Replacement

            //Organisms:
            Organisms.Clear();

            Organisms.AddRange(next_generation);


            //Species:
            Species.Clear();

            foreach (Species species in next_species)
            {
                Species.Add(species);
            }

            #endregion Replacement


            RemoveExtinctions();


            CompatibilityDistance += CD_function.Invoke(Species.Count);
        }
Beispiel #4
0
 /// <summary>
 /// Removes all stored extinct species (species with no organisms). See <see cref="NEAT.NEATClient.Evolve"/> before using!
 /// </summary>
 public void RemoveExtinctions()
 {
     Species.RemoveWhere(x => x.Size == 0);
 }
Beispiel #5
0
        /// <summary>
        /// Separates the current organisms into the correct species. Makes new species and deletes extinct species as needed. See <see cref="NEAT.NEATClient.Evolve"/> before using!
        /// </summary>
        public void Speciate()
        {
            foreach (Organism organism in Organisms)
            {
                bool found_species = false;

                foreach (Species species in Species)
                {
                    Organism random_organism = species.GetRandomOrganism(Pedigree.Random, organism);


                    if (random_organism == null)    //The organism we're at is the only organism in the species we're at. See if we should leave it in this species.
                    {
                        bool kill_species = false;

                        IEnumerable <Species> all_other_species = Species.Where(x => x != species);

                        foreach (Species other_species in all_other_species)
                        {
                            Organism other_random_organism = other_species.GetRandomOrganism(Pedigree.Random);  //No need to exclude the organism because it can't be here.

                            if (organism.Genome.Distance(other_random_organism.Genome) < CompatibilityDistance) //The organism can fit in another species, put it there.
                            {
                                organism.Species.RemoveOrganism(organism);

                                other_species.AddOrganism(organism);


                                kill_species = true;
                                break;
                            }
                        }


                        if (kill_species)   //This species no longer has any organisms, it is now extinct.
                        {
                            Species.Remove(species);
                        }


                        found_species = true;
                        break;
                    }


                    if (organism.Genome.Distance(random_organism.Genome) < CompatibilityDistance)
                    {
                        if (organism.Species != random_organism.Species)    //If the species to set is actually different.
                        {
                            Species original_species = organism.Species;


                            original_species?.RemoveOrganism(organism);

                            species.AddOrganism(organism);


                            if (original_species?.Size == 0) //This species just went extinct.
                            {
                                Species.Remove(original_species);
                            }
                        }

                        found_species = true;
                        break;
                    }
                }

                if (!found_species)
                {
                    Species original_species = organism.Species;


                    original_species?.RemoveOrganism(organism);


                    Species new_species = new Species();

                    Species.Add(new_species);

                    new_species.AddOrganism(organism);


                    if (original_species?.Size == 0) //This species just went extinct.
                    {
                        Species.Remove(original_species);
                    }
                }
            }
        }
Beispiel #6
0
        /// <summary>
        /// Breed
        /// </summary>
        private void Breed()
        {
            // Logs Setup
            int weightMutationNb          = 0;
            int addConnectionNb           = 0;
            int addNodeNb                 = 0;
            int enableDisableConnectionNb = 0;

            _mutationLogs = "";

            while (_nextEvaluationGenomes.Count() < _config.populationSize)
            {
                Genome child = null;
                Genome mom   = null;
                Genome dad   = null;

                // Get Child

                Species species   = null;
                int     maxToKeep = ((_config.populationSize * _config.percentageToKeep) / 100) - 1;
                if (_config.species)
                {
                    species = GetRandomSpecies(_r);
                }
                if (_config.crossover)
                {
                    if (species != null)
                    {
                        mom = GetRandomGenome(species, _r);
                        dad = GetRandomGenome(species, _r);
                    }
                    else
                    {
                        mom = _genomes[UnityEngine.Random.Range(0, maxToKeep)];
                        dad = _genomes[UnityEngine.Random.Range(0, maxToKeep)];
                    }

                    // Crossover between Mom & Dad
                    child = mom.Fitness >= dad.Fitness ? Genome.Crossover(mom, dad, _r, _config.disabledConnectionInheritChance) : Genome.Crossover(dad, mom, _r, _config.disabledConnectionInheritChance);
                }
                else
                {
                    child = species != null ? new Genome(GetRandomGenome(species, _r)) : new Genome(_genomes[UnityEngine.Random.Range(0, maxToKeep)]);
                }

                // Weights Mutation
                if ((float)_r.NextDouble() < _config.mutationRate)
                {
                    child.WeightsMutation(_r);
                    weightMutationNb++;
                }

                if (_config.genomeMutations)
                {
                    // Add Connection Mutation
                    if ((float)_r.NextDouble() < _config.addConnectionRate)
                    {
                        // If for Logs
                        if (child.AddConnectionMutation(_r, _connectionInnovation, 10))
                        {
                            addConnectionNb++;
                        }
                    }

                    // Add Node Mutation
                    if ((float)_r.NextDouble() < _config.addNodeRate)
                    {
                        child.AddNodeMutation(_r, _connectionInnovation, _nodeInnovation);
                        addNodeNb++;
                    }

                    // Enable/Disable a Random Connection
                    if ((float)_r.NextDouble() < _config.enableDisableRate)
                    {
                        // If for Logs
                        if (child.EnableOrDisableRandomConnection())
                        {
                            enableDisableConnectionNb++;
                        }
                    }
                }

                // Add Child to Next Evaluation Genomes
                _nextEvaluationGenomes.Add(child);
            }

            _mutationLogs += string.Format(
                "Weights Mutation: {0}, Add Connection: {1}, Add Node: {2}, Enable/Disable Connection: {3}\nCrossover is {4}, Genome Mutations is {5}, Species is {6}",
                weightMutationNb,
                addConnectionNb,
                addNodeNb,
                enableDisableConnectionNb,
                _config.crossover,
                _config.genomeMutations,
                _config.species
                );

            _genomes.Clear();
            _genomes = new List <Genome>(_nextEvaluationGenomes);
            _nextEvaluationGenomes = new List <Genome>();
        }
Beispiel #7
0
 /// <summary>
 /// Eliminate the species with its genomes.
 /// </summary>
 private void EliminateSpecies(Species speciesTarget)
 {
     Genomes.RemoveAll(x => speciesTarget.Genomes.Contains(x));
     SpeciesCtrl.SpeciesList.Remove(speciesTarget);
 }