Exemplo n.º 1
0
        public void Generate()
        {
            IRouletteWheel rouletteWheel = breedingFactory.CreateRouletteWheel(generation);

            breeder.SetRouletteWheel(rouletteWheel);
            breeder.CalcFitness(generation);

            Solution[] newGeneration = new Solution[population];


            for (int i = 0; i < population; i++)
            {
                newGeneration[i] = breeder.Breed();
            }
            logger.logBestFitSolution(writer, FindBestFit());
            generation = newGeneration;
        }
        private void createNextGeneration(ITrainingSession bestPerformer)
        {
            Stopwatch watch = new Stopwatch();

            watch.Start();

            int numberOfTopPerformersToChoose = (int)(_generationConfig.GenerationPopulation * 0.50);
            int numToBreed = (int)(_generationConfig.GenerationPopulation * 0.35);
            int numToGen   = (int)(_generationConfig.GenerationPopulation * 0.15);

            if (numberOfTopPerformersToChoose + numToBreed + numToGen < _generationConfig.GenerationPopulation)
            {
                numToGen += _generationConfig.GenerationPopulation -
                            (numberOfTopPerformersToChoose + numToBreed + numToGen);
            }

            var sessions = _generation.GetBestPerformers(numberOfTopPerformersToChoose);

            if (bestPerformer != null)
            {
                LoggerFactory.GetLogger().Log(LogLevel.Info, "Best performer found for creating generation");
                if (sessions.All(s => s.NeuralNet.GetGenes() != bestPerformer.NeuralNet.GetGenes()))
                {
                    LoggerFactory.GetLogger()
                    .Log(LogLevel.Info,
                         $"Best performer adding to sessions with eval {bestPerformer.GetSessionEvaluation()}");
                    sessions[sessions.Count - 1] = bestPerformer;
                    sessions = sessions.OrderByDescending(s => s.GetSessionEvaluation()).ToList();
                    LoggerFactory.GetLogger()
                    .Log(LogLevel.Info, $"session 0 eval: {sessions[0].GetSessionEvaluation()}");
                }
                else
                {
                    LoggerFactory.GetLogger()
                    .Log(LogLevel.Info,
                         $"Best performer already in generation: not adding.");
                }
            }

            _history.AddEval(sessions[0].GetSessionEvaluation());

            var mutateChance = DetermineMutateChance();

            IList <INeuralNetwork> children = _breeder.Breed(sessions, numToBreed);
            var newSessions = new List <ITrainingSession>();
            //Allow the very top numToLiveOn sessions to be added to next generation untouched
            int numToLiveOn      = sessions.Count / 10;
            var sessionsToLiveOn = sessions.Take(numToLiveOn).ToList();

            newSessions.AddRange(sessionsToLiveOn);

            //try to mutate session that will live on 1 by 1
            var mutatedTop = GetMutatedNetworks(sessionsToLiveOn.Select(s => s.NeuralNet), mutateChance);

            //or each session that lived on that was mutated, remove last top performer, then mutate remaining top performers in batch and add
            sessions = sessions.Skip(numToLiveOn).ToList();
            var sessionSubset = sessions.Take(sessions.Count - mutatedTop.Count);
            IList <INeuralNetwork> toKeepButPossiblyMutate = sessionSubset.Select(session => session.NeuralNet).ToList();
            IList <INeuralNetwork> newNetworks             = getNewNetworks(numToGen, mutateChance);

            List <INeuralNetwork> toTryMutate = new List <INeuralNetwork>();

            //try to mutate both new networks as well as all the top performers we wanted to keep
            toTryMutate.AddRange(toKeepButPossiblyMutate);
            toTryMutate.AddRange(newNetworks);
            bool didMutate;
            IList <INeuralNetwork> maybeMutated = _mutator.Mutate(toTryMutate, mutateChance, out didMutate);

            List <INeuralNetwork> allToAdd = new List <INeuralNetwork>();

            allToAdd.AddRange(mutatedTop);
            allToAdd.AddRange(children);
            allToAdd.AddRange(maybeMutated);

            newSessions.AddRange(allToAdd.Select((net, sessionNumber) => new TrainingSession(net, _evaluatableFactory.Create(net), sessionNumber)));
            _generation = new Generation(newSessions, _generationConfig);

            watch.Stop();
            LoggerFactory.GetLogger().Log(LogLevel.Debug, $"create generation runtime (sec): {watch.Elapsed.TotalSeconds}");
            watch.Reset();
        }
Exemplo n.º 3
0
        public void Solve(BionicModel model, BionicSolverSettings settings)
        {
            if (model == null)
            {
                throw new ArgumentNullException("model");
            }

            if (settings == null)
            {
                throw new ArgumentNullException("settings");
            }

            OnSolverStarting(new EventArgs());

            IInitialPopulationGenerator initializer = InitialPopulationGeneratorFactory.CreateInitialPopulationGenerator();
            ISelector selector = SelectorFactory.CreateSelector();
            IBreeder  breeder  = BreederFactory.CreateBreeder();

            // 1. Zeroing generation number
            model.CurrentGeneration = 0;

            OnSolverStarted(new EventArgs());

            // 2. Creating initial population
            CopyIndividuals(initializer.GenerateInitialPopulation(settings.InitialPopulationSize, model.Attributes), model.CurrentPopulation);
            CalculateFitness(model, model.CurrentPopulation, settings);
            model.ApplyFunctionalConstraints();

            OnPopulationUpdated(new EventArgs());

            while (model.CurrentGeneration < settings.MaxGenerations)
            {
                // 3. Selecting most fit individuals
                IEnumerable <Individual> fitIndividuals = selector.Select(model.CurrentPopulation, model.FitnessCriterion, settings.SelectionCap);
                if (fitIndividuals.Count() == 0)
                {
                    OnSolverFinished(new SolverFinishedEventArgs("All individuals are inactive"));
                    return;
                }

                // Selected subpopulation will contain only selected active individuals
                Population selectedSubPopulation = new Population(fitIndividuals.Count());
                foreach (Individual fitIndividual in fitIndividuals)
                {
                    selectedSubPopulation.Add(fitIndividual);
                }

                // 4. Breeding the selected ones
                IEnumerable <Individual> descendants = breeder.Breed(selectedSubPopulation, model.Attributes,
                                                                     settings.DescendantsRangePercent, settings.DescendantsNum, model.CurrentGeneration + 1);
                if (descendants.Count() == 0)
                {
                    OnSolverFinished(new SolverFinishedEventArgs("No descendants was created"));
                    return;
                }

                // Descendants subpopulation will contain only new individuals
                Population descendantsSubPopulation = new Population(descendants.Count());
                foreach (Individual descendant in descendants)
                {
                    descendantsSubPopulation.Add(descendant);
                }

                // 5. Calculating fitness of the descendants
                CalculateFitness(model, descendantsSubPopulation, settings);
                // At this point, all descendants are still active, although
                // there may be individuals that don't fit f. c.

                // 6. Forming new population
                if (settings.ApplyElitism)
                {
                    // First unite descendants with their parents (elitism)
                    // We can do this without fear of ID collision because this
                    // was taken into account on the breeding step
                    CopyIndividuals(descendantsSubPopulation, selectedSubPopulation);

                    // Now this united population becomes current, we just
                    // throw away old individuals
                    model.CurrentPopulation.Clear();
                    CopyIndividuals(selectedSubPopulation, model.CurrentPopulation);
                }
                else
                {
                    // We throw away parents and old individuals,
                    // descendants are taking over the place
                    model.CurrentPopulation.Clear();
                    CopyIndividuals(descendantsSubPopulation, model.CurrentPopulation);
                }

                model.ApplyFunctionalConstraints();

                // 7. Updating current generation number
                model.CurrentGeneration = model.CurrentPopulation.Max(ind => ind.Value.GenerationNumber);

                OnPopulationUpdated(new EventArgs());
            }

            OnSolverFinished(new SolverFinishedEventArgs());
        }