Пример #1
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());
        }