/// <summary>
 /// Represents an Entity able to execute the Genetic Algorithm for the input parameters
 /// </summary>
 /// <param name="problem">Instance of a Problem to be Solved</param>
 /// <param name="selectionMethodType">The Method to Be used for Parent Selection in Crossover Methods</param>
 /// <param name="tourSize">In case the 'Tour' Method is chosen as the current Selection Method, this parameter will be considered in its evaluation</param>
 /// <param name="crossoverMethodType">The Method to be used for Crossover between two parents</param>
 /// <param name="reinsertionMethodType">The Method by which Individuals are chosen to be part of the next Generation</param>
 /// <param name="populationSize">The Individual Count in a Population that is considered to be a Generation</param>
 /// <param name="numberOfGenerations">The Number of Generations to run before the algorithm returns an Result</param>
 /// <param name="crossoverPct">The Crossover percentage involved in the calculation</param>
 /// <param name="mutationPct">The Mutation percentage involved in the calculation</param>
 public MonoObjectiveGeneticAlgorithm(ProblemBase problem, SelectionMethodBase selectionMethod, CrossoverMethodBase crossoverMethod, ReinsertionMethodBase reinsertionMethod, int populationSize, int numberOfGenerations, int mutationPct)
     : base(problem, populationSize, numberOfGenerations)
 {
     this.mutationPct = mutationPct;
     this.selectionMethod = selectionMethod;
     selectionMethod.Problem = problem;
     this.crossoverMethod = crossoverMethod;
     crossoverMethod.Problem = problem;
     this.reinsertionMethod = reinsertionMethod;
 }
 /// <summary>
 /// Represents an Entity able to execute the Genetic Algorithm for the input parameters
 /// </summary>
 /// <param name="problem">Instance of a Problem to be Solved</param>
 /// <param name="selectionMethodType">The Method to Be used for Parent Selection in Crossover Methods</param>
 /// <param name="tourSize">In case the 'Tour' Method is chosen as the current Selection Method, this parameter will be considered in its evaluation</param>
 /// <param name="crossoverMethodType">The Method to be used for Crossover between two parents</param>
 /// <param name="reinsertionMethodType">The Method by which Individuals are chosen to be part of the next Generation</param>
 /// <param name="populationSize">The Individual Count in a Population that is considered to be a Generation</param>
 /// <param name="numberOfGenerations">The Number of Generations to run before the algorithm returns an Result</param>
 /// <param name="crossoverPct">The Crossover percentage involved in the calculation</param>
 /// <param name="mutationPct">The Mutation percentage involved in the calculation</param>
 public MonoObjectiveGeneticAlgorithm(ProblemBase problem, SelectionMethodBase selectionMethod, CrossoverMethodBase crossoverMethod, ReinsertionMethodBase reinsertionMethod, int populationSize, int numberOfGenerations, int mutationPct)
     : base(problem, populationSize, numberOfGenerations)
 {
     this.mutationPct        = mutationPct;
     this.selectionMethod    = selectionMethod;
     selectionMethod.Problem = problem;
     this.crossoverMethod    = crossoverMethod;
     crossoverMethod.Problem = problem;
     this.reinsertionMethod  = reinsertionMethod;
 }
        private Population_MonoObjective_AG RunGeneration(Population_MonoObjective_AG currentGeneration, SelectionMethodBase selectionMethod, CrossoverMethodBase crossoverMethod, /*IReinsertionMethod reinsertionMethod, */ReinsertionMethodBase reinsertionMethod)
        {
            Population_MonoObjective_AG recentlyBorn = new Population_MonoObjective_AG(Problem, InitialPopulationSize);

            int expectedChildCount = ((InitialPopulationSize * reinsertionMethod.OffspringPercentage) / 100);

            while (recentlyBorn.IndividualCount < expectedChildCount) {
                IndividualBase parent1 = null, parent2 = null, child1 = null, child2 = null;
                selectionMethod.Execute(currentGeneration, out parent1, out parent2);
                crossoverMethod.Execute(parent1, parent2, out child1, out child2);
                recentlyBorn.AddIndividual(child1);
                recentlyBorn.AddIndividual(child2);
            }

            int mutatedChildCount = ((recentlyBorn.IndividualCount * mutationPct) / 100);
            for (int idx = 0; idx < mutatedChildCount; ++idx) {
                IndividualBase randomIndividual = recentlyBorn.GetRandomIndividual();
                Problem.MutateIndividual(randomIndividual);
            }

            IndividualBase individual = null;
            for (int idx = 0; idx < recentlyBorn.IndividualCount; ++idx) {
                individual = recentlyBorn.Content[idx];
                Problem.ValidateIndividual(individual);
                IndividualEvaluator.Execute(individual, Problem);
            }

            Population_MonoObjective_AG newGeneration = reinsertionMethod.Execute(currentGeneration, recentlyBorn);
            return newGeneration;
        }
        private Population_MonoObjective_AG RunGeneration(Population_MonoObjective_AG currentGeneration, SelectionMethodBase selectionMethod, CrossoverMethodBase crossoverMethod, /*IReinsertionMethod reinsertionMethod, */ ReinsertionMethodBase reinsertionMethod)
        {
            Population_MonoObjective_AG recentlyBorn = new Population_MonoObjective_AG(Problem, InitialPopulationSize);

            int expectedChildCount = ((InitialPopulationSize * reinsertionMethod.OffspringPercentage) / 100);

            while (recentlyBorn.IndividualCount < expectedChildCount)
            {
                IndividualBase parent1 = null, parent2 = null, child1 = null, child2 = null;
                selectionMethod.Execute(currentGeneration, out parent1, out parent2);
                crossoverMethod.Execute(parent1, parent2, out child1, out child2);
                recentlyBorn.AddIndividual(child1);
                recentlyBorn.AddIndividual(child2);
            }

            int mutatedChildCount = ((recentlyBorn.IndividualCount * mutationPct) / 100);

            for (int idx = 0; idx < mutatedChildCount; ++idx)
            {
                IndividualBase randomIndividual = recentlyBorn.GetRandomIndividual();
                Problem.MutateIndividual(randomIndividual);
            }

            IndividualBase individual = null;

            for (int idx = 0; idx < recentlyBorn.IndividualCount; ++idx)
            {
                individual = recentlyBorn.Content[idx];
                Problem.ValidateIndividual(individual);
                IndividualEvaluator.Execute(individual, Problem);
            }

            Population_MonoObjective_AG newGeneration = reinsertionMethod.Execute(currentGeneration, recentlyBorn);

            return(newGeneration);
        }