private void DoPostSolveActivities(GeneticAlgorithmState state)
        {
            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine($"Best solution found: {state.BestChromosomeOptimizationResult.HighestLambdaId}");
            Console.ForegroundColor = ConsoleColor.DarkCyan;

            Console.WriteLine($"Genetic Algorithm exited after {(double)state.ElapsedTime.ElapsedMilliseconds / 1000} seconds. " +
                              $"Generations cultured: {state.NumberOfGenerations}.");

            _outputWriter.SaveOutputToTheFile(state.BestChromosomeOptimizationResult, state.BestChromosomeNetworkSolution.PathAllocations, _currentFileName);
        }
        private void PrintBestAlgorithmInGeneration(GeneticAlgorithmState state, bool bestResult)
        {
            if (bestResult)
            {
                Console.ForegroundColor = ConsoleColor.Green;
            }

            Console.WriteLine($"Best solution in generation { state.NumberOfGenerations }: " + state.BestChromosomeOptimizationResult.HighestLambdaId);

            if (bestResult)
            {
                Console.ForegroundColor = ConsoleColor.DarkCyan;
            }
        }
        public void Solve()
        {
            var state = new GeneticAlgorithmState
            {
                ElapsedTime         = Stopwatch.StartNew(),
                NumberOfGenerations = 0,
                NumberOfGenerationsWithoutImprovement = 0,
                NumberOfMutations = 0,
                BestChromosomeOptimizationResult = null,
                BestChromosomeFitness            = 0
            };


            var random = new Random(_parameters.RandomSeed);

            var population = GenerateInitialPopulation(random);

            EvaluateFitness(population.Chromosomes);

            var bestChromosome = population.Chromosomes.OrderByDescending(x => x.Fitness).First();

            state.BestChromosomeNetworkSolution    = ((NetworkSolution)bestChromosome).CloneNS();
            state.BestChromosomeOptimizationResult = CalculateNetworkSolutionOptimizationResult((NetworkSolution)bestChromosome);
            if (state.BestChromosomeOptimizationResult.HighestLambdaId != 0)
            {
                state.BestChromosomeFitness = (1000000 / state.BestChromosomeOptimizationResult.HighestLambdaId);
            }
            else
            {
                state.BestChromosomeFitness = int.MaxValue;
            }

            PrintBestAlgorithmInGeneration(state, true);

            while (!EvaluateStoppingCriteria(state))
            {
                EvaluateFitness(population.Chromosomes);

                var bestChromosomeInGeneration = population.Chromosomes.OrderByDescending(x => x.Fitness).First();

                if (bestChromosomeInGeneration.Fitness > state.BestChromosomeFitness)
                {
                    state.BestChromosomeNetworkSolution    = ((NetworkSolution)bestChromosomeInGeneration).CloneNS();
                    state.BestChromosomeOptimizationResult = CalculateNetworkSolutionOptimizationResult((NetworkSolution)bestChromosomeInGeneration);
                    state.BestChromosomeFitness            = (1000000 / state.BestChromosomeOptimizationResult.HighestLambdaId);

                    state.NumberOfGenerationsWithoutImprovement = 0;

                    PrintBestAlgorithmInGeneration(state, true);
                }
                else
                {
                    state.NumberOfGenerationsWithoutImprovement++;

                    PrintBestAlgorithmInGeneration(state, false);
                }

                var eliteOffsprings       = SelectEliteOffsprings(population);
                var crossoveredOffsprings = CrossoverOffsprings(population, eliteOffsprings.Count, random);
                var mutatedOffsprings     = MutateOffsprings(crossoveredOffsprings, state, random);

                EvaluateFitness(mutatedOffsprings);

                population = SelectSurvivors(population, eliteOffsprings, mutatedOffsprings);

                state.NumberOfGenerations++;
            }

            state.ElapsedTime.Stop();

            DoPostSolveActivities(state);
        }
 private bool EvaluateStoppingCriteria(GeneticAlgorithmState state) =>
 _parameters.StoppingCriteria switch
 {
        private List <Chromosome> MutateOffsprings(List <Chromosome> crossoveredOffsprings, GeneticAlgorithmState state, Random random)
        {
            List <Chromosome> mutatedOffsprings = new List <Chromosome>();

            foreach (var offspring in crossoveredOffsprings)
            {
                var rand = random.NextDouble();
                if (rand >= _parameters.MutationProbability)
                {
                    state.NumberOfMutations++;

                    mutatedOffsprings.Add(offspring.Mutate(random));
                }
                else
                {
                    mutatedOffsprings.Add(offspring);
                }
            }

            return(mutatedOffsprings);
        }