private FunctionResult GetFunctionResultForChromosomes(BinaryChromosome chromosome1, BinaryChromosome chromosome2, Range range)
        {
            var x1Best = BinaryUtils.BinaryToDecimalRepresentation(chromosome1.BinaryRepresentation, range, NumberOfBitsInChromosome);
            var x2Best = BinaryUtils.BinaryToDecimalRepresentation(chromosome2.BinaryRepresentation, range, NumberOfBitsInChromosome);

            return(new FunctionResult(Function.Compute(x1Best, x2Best), x1Best, x2Best));
        }
 private double CalculateFunctionValue(List <BinaryChromosome> chromosomes, Range range, double bitsInChromosome)
 {
     if (chromosomes.Count != 2)
     {
         throw new ArgumentException("Incorrect chromosomes amount.");
     }
     return(function.Compute(
                BinaryUtils.BinaryToDecimalRepresentation(chromosomes[0].BinaryRepresentation, range, bitsInChromosome),
                BinaryUtils.BinaryToDecimalRepresentation(chromosomes[1].BinaryRepresentation, range, bitsInChromosome)));
 }
        private Dictionary <List <BinaryChromosome>, double> GetFunctionValueByChromosome(List <BinaryChromosome> chromosomes, Range range, double bitsInChromosome)
        {
            var valuesByChromosomes = new Dictionary <List <BinaryChromosome>, double>(chromosomes.Count);

            for (int i = 0; i < chromosomes.Count; i += 2)
            {
                valuesByChromosomes.Add(new List <BinaryChromosome> {
                    chromosomes[i], chromosomes[i + 1]
                },
                                        function.Compute(
                                            BinaryUtils.BinaryToDecimalRepresentation(chromosomes[i].BinaryRepresentation, range, bitsInChromosome),
                                            BinaryUtils.BinaryToDecimalRepresentation(chromosomes[i + 1].BinaryRepresentation, range, bitsInChromosome)));
            }
            return(valuesByChromosomes);
        }
        public OptimizationResult Optimize(InputDataEntity inputDataEntity)
        {
            InputDataEntity          = inputDataEntity;
            NumberOfBitsInChromosome = PopulationService.CalculateNumberOfBitsInChromosome(inputDataEntity.DataRange, inputDataEntity.Accuracy);
            BinaryChromosomes        = PopulationService.GeneratePopulation(inputDataEntity.PopulationAmount, NumberOfBitsInChromosome);
            // Method selection
            ISelection selectionMethod                = GetSelectionMethod(InputDataEntity.SelectionMethod, inputDataEntity);
            ICross     crossMethod                    = GetCrossMethod(InputDataEntity.CrossMethod);
            IMutation  mutationMethod                 = GetMutationMethod(InputDataEntity.MutationMethod);
            var        bestOfEachEpoch                = new List <FunctionResult>();
            List <BinaryChromosome> tmpBest           = new List <BinaryChromosome>();
            List <double>           means             = new List <double>();
            List <double>           standardDeviation = new List <double>();
            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();
            for (int i = 0; i < InputDataEntity.EpochsAmount; i++)
            {
                List <BinaryChromosome> newPopulation = selectionMethod.ApplySelection(BinaryChromosomes, inputDataEntity.DataRange, NumberOfBitsInChromosome);
                if (i != 0)
                {
                    double newValue = GetFunctionResultForChromosomes(newPopulation[0], newPopulation[1], inputDataEntity.DataRange).FunctionValue;
                    double oldValue = GetFunctionResultForChromosomes(tmpBest[0], tmpBest[1], inputDataEntity.DataRange).FunctionValue;
                    if ((inputDataEntity.Maximize == false && newValue > oldValue) || (inputDataEntity.Maximize == true && newValue < oldValue))
                    {
                        newPopulation.InsertRange(0, tmpBest);
                    }
                    else
                    {
                        newPopulation.InsertRange(newPopulation.Count - 1, tmpBest);
                    }
                }
                bestOfEachEpoch.Add(GetFunctionResultForChromosomes(newPopulation[0], newPopulation[1], inputDataEntity.DataRange));
                tmpBest.Clear();
                for (int j = 0; j < inputDataEntity.EliteStrategyAmount * 2; j++)
                {
                    tmpBest.Add(newPopulation[j]);
                }
                means.Add(CalculateMean(newPopulation, inputDataEntity.DataRange));
                standardDeviation.Add(CalculateDeviation(newPopulation, inputDataEntity.DataRange, means[i]));
                List <BinaryChromosome> crossedPopulation        = crossMethod.Cross(newPopulation, InputDataEntity.CrossProbability);
                List <BinaryChromosome> mutatedPopulation        = mutationMethod.Mutate(crossedPopulation, InputDataEntity.MutationProbability);
                List <BinaryChromosome> populationAfterInversion = Inversion.PerformInversion(mutatedPopulation, InputDataEntity.InversionProbability);
                BinaryChromosomes = populationAfterInversion;
                if (BinaryChromosomes.Count <= 2)
                {
                    break;
                }
            }

            var    bestIndividuals = selectionMethod.ApplySelection(BinaryChromosomes, inputDataEntity.DataRange, NumberOfBitsInChromosome).Take(2).ToArray();
            double x1       = BinaryUtils.BinaryToDecimalRepresentation(bestIndividuals[0].BinaryRepresentation, inputDataEntity.DataRange, NumberOfBitsInChromosome);
            double x2       = BinaryUtils.BinaryToDecimalRepresentation(bestIndividuals[1].BinaryRepresentation, inputDataEntity.DataRange, NumberOfBitsInChromosome);
            double extremum = Function.Compute(x1, x2);

            stopwatch.Stop();
            return(new OptimizationResult
            {
                ExtremeValue = extremum,
                X1 = x1,
                X2 = x2,
                BestFromPreviousEpochs = bestOfEachEpoch,
                MeanFromPreviousEpochs = means,
                StandardDeviation = standardDeviation,
                TimeElapsed = stopwatch.ElapsedMilliseconds
            });
        }