public void Execute(Logger.Logger logger)
        {
            void logGeneration(int generation, double bestFitness, double averageFitness, double worstFitness)
            {
                logger.LogGeneticPeriodicTabu(generation, bestFitness, averageFitness, worstFitness, null);
            }

            void logOutro(List <double> bestFitnesses)
            {
                logger.LogOutro(bestFitnesses);
            }

            void logTabuCycle(int tabuCycle, double bestFitness, double currentFitness)
            {
                logger.LogGeneticPeriodicTabu(tabuCycle, bestFitness, null, null, currentFitness);
            }

            var populations = new List <List <IIndividual> >();

            for (var i = 0; i < Parameters.GeneticParameters.NumAlgorithmIterations; i++)
            {
                populations.Add(Genetic.InitializePopulation().Select(indiv =>
                {
                    return(Tabu.Execute(logTabuCycle, logOutro, indiv)[0]);
                }).ToList());
            }

            Genetic.Execute(logGeneration, logOutro, Parameters.TabuParameters.NumTabuSearches, populations);
        }
        public void Execute(Logger.Logger logger)
        {
            void logGeneration(int generation, double bestFitness, double averageFitness, double worstFitness)
            {
                logger.LogGeneticThenSaTtp1(generation, bestFitness, averageFitness, worstFitness, null, null);
            }

            void logOutro(List <double> bestFitnesses)
            {
                logger.LogOutro(bestFitnesses);
            }

            var finalPopulations = Genetic.Execute(logGeneration, logOutro);

            void logAnnealingCycle(int annealingCycle, double globalBestFitness, double bestFitness, double currentFitness)
            {
                logger.LogGeneticThenSaTtp1(annealingCycle, globalBestFitness, null, null, bestFitness, currentFitness);
            }

            foreach (var population in finalPopulations)
            {
                var         bestFitness = double.MinValue;
                IIndividual bestIndiv   = null;
                population.ForEach(indiv =>
                {
                    var fitness = Problem.Fitness(indiv);
                    if (fitness > bestFitness)
                    {
                        bestFitness = fitness;
                        bestIndiv   = indiv;
                    }
                });

                if (bestIndiv == null)
                {
                    continue;
                }

                Annealing.Execute(logAnnealingCycle, logOutro, bestIndiv, Parameters.GeneticParameters.NumGenerations);
            }
        }