Beispiel #1
0
        /// <summary>
        /// Solves the given problem.
        /// </summary>
        /// <returns></returns>
        public override TSolution Solve(TProblem problem, TObjective objective, out TFitness fitness)
        {
            var population = new Individual <TSolution, TFitness> [_settings.PopulationSize];

            // generate initial population.
            var solutionCount = 0;

            while (solutionCount < _settings.PopulationSize)
            {
                TFitness localFitness;
                var      solution = _generator.Solve(problem, objective, out localFitness);
                population[solutionCount] = new Individual <TSolution, TFitness>()
                {
                    Fitness  = localFitness,
                    Solution = solution
                };
                solutionCount++;
            }

            // sort population.
            Array.Sort(population, (x, y) =>
            {
                return(objective.CompareTo(problem, x.Fitness, y.Fitness));
            });
            var bestIndividual = population[0];

            this.ReportIntermidiateResult(bestIndividual.Solution);

            // mutate/crossover population.
            var stagnation           = 0;
            var generation           = 0;
            var elitism              = (int)(_settings.PopulationSize * (_settings.ElitismPercentage / 100.0));
            var crossOver            = (int)(_settings.PopulationSize * (_settings.CrossOverPercentage / 100.0));
            var crossOverIndividuals = new Individual <TSolution, TFitness> [crossOver];
            var exclude              = new HashSet <int>();

            while (stagnation < _settings.StagnationCount &&
                   generation < _settings.MaxGenerations &&
                   !this.IsStopped)
            {
                // select individuals for crossover.
                exclude.Clear();
                for (int i = 0; i < crossOver; i++)
                {
                    // select individual.
                    var selected = -1;
                    while (selected < 0)
                    {
                        selected = _selection.Select(problem, objective, population, exclude);
                    }
                    crossOverIndividuals[i] = population[selected];
                    exclude.Add(selected);
                }

                // replace part of the population by offspring.
                for (int i = elitism; i < population.Length; i++)
                {
                    // take two random parents.
                    var individual1 = _random.Next(crossOver);
                    var individual2 = _random.Next(crossOver - 1);
                    if (individual1 <= individual2)
                    { // make sure they are different.
                        individual2++;
                    }

                    // create offspring.
                    TFitness offspringFitness;
                    var      offspring = _crossOver.Apply(problem, objective, population[individual1].Solution,
                                                          population[individual2].Solution, out offspringFitness);
                    population[i] = new Individual <TSolution, TFitness>()
                    {
                        Solution = offspring,
                        Fitness  = offspringFitness
                    };
                }

                // mutate part of the population.
                for (int i = elitism; i < population.Length; i++)
                {
                    if (_random.Next(100) <= _settings.MutationPercentage)
                    { // ok, mutate this individual.
                        TFitness mutatedDelta;
                        if (_mutation.Apply(problem, objective, population[i].Solution, out mutatedDelta))
                        { // mutation succeeded.
                            population[i].Fitness = objective.Subtract(problem, population[i].Fitness, mutatedDelta);
                        }
                    }
                }

                // sort new population.
                Array.Sort(population, (x, y) =>
                {
                    return(objective.CompareTo(problem, x.Fitness, y.Fitness));
                });
                if (objective.IsBetterThan(problem, bestIndividual.Fitness, population[0].Fitness))
                {                       // a better individual was found.
                    bestIndividual = population[0];
                    stagnation     = 0; // reset stagnation flag.
                    this.ReportIntermidiateResult(bestIndividual.Solution);
                }
                else
                { // no better solution found.
                    stagnation++;
                }
            }

            fitness = bestIndividual.Fitness;
            return(bestIndividual.Solution);
        }