예제 #1
0
        /// <summary>
        /// Runs each Neural Network of the population through the fitness function and assigns the fitnesses.
        /// Overloaded for running on multiple threads. default is unthreaded.
        /// </summary>
        public void Run()
        {
            Dictionary <int, double> fitnesses = new Dictionary <int, double>();
            double totalfitness = 0;

            if (threaded)
            {
                Thread thread1 = new Thread(() =>
                {
                    for (int i = 0; i < Networks.Count / 4; i++)
                    {
                        NeuralNetwork NN = Networks.ElementAt(i);
                        double fitness   = run(NN);
                        totalfitness    += fitness;
                        lock (fitnesses)
                        {
                            fitnesses.Add(i, fitness);
                        }
                        //Console.WriteLine(i + " -> " + fitness);
                    }
                });
                Thread thread2 = new Thread(() =>
                {
                    for (int i = Networks.Count / 4; i < Networks.Count / 2; i++)
                    {
                        NeuralNetwork NN = Networks.ElementAt(i);
                        double fitness   = run(NN);
                        totalfitness    += fitness;
                        lock (fitnesses)
                        {
                            fitnesses.Add(i, fitness);
                        }
                        //Console.WriteLine(i + " -> " + fitness);
                    }
                });
                Thread thread3 = new Thread(() =>
                {
                    for (int i = Networks.Count / 2; i < 3 * Networks.Count / 4; i++)
                    {
                        NeuralNetwork NN = Networks.ElementAt(i);
                        double fitness   = run(NN);
                        totalfitness    += fitness;
                        lock (fitnesses)
                        {
                            fitnesses.Add(i, fitness);
                        }
                        //Console.WriteLine(i + " -> " + fitness);
                    }
                });
                Thread thread4 = new Thread(() =>
                {
                    for (int i = 3 * Networks.Count / 4; i < Networks.Count; i++)
                    {
                        NeuralNetwork NN = Networks.ElementAt(i);
                        double fitness   = run(NN);
                        totalfitness    += fitness;
                        lock (fitnesses)
                        {
                            fitnesses.Add(i, fitness);
                        }
                        //Console.WriteLine(i + " -> " + fitness);
                    }
                });

                thread1.Start();
                thread2.Start();
                thread3.Start();
                thread4.Start();

                thread1.Join();
                thread2.Join();
                thread3.Join();
                thread4.Join();
            }
            else
            {
                int count = 0;
                foreach (NeuralNetwork NN in Networks)
                {
                    double fitness = run(NN);
                    totalfitness += fitness;
                    fitnesses.Add(count, fitness);
                    //Console.WriteLine(count + " -> " + fitness);
                    count++;
                }
            }

            AvgPopFitness = totalfitness / Networks.Count;
            BestNetwork   = null;

            for (int i = 0; i < Networks.Count(); i++)
            {
                fitnesses.TryGetValue(i, out double fitness);
                if (BestNetwork == null || fitness > BestNetwork.Fitness)
                {
                    BestNetwork = Networks.ElementAt(i);
                }
                Networks.ElementAt(i).Fitness = fitness;
            }
            //Console.WriteLine("Run: " + isConsistent());
        }
예제 #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());
        }