public ICandidateSolution <ItemList> Mutate(ICandidateSolution <ItemList> candidate, Knapsack input, double mutationRate)
        {
            for (int i = 0; i < candidate.CandidateItem.Count; i++)
            {
                if (input.Randomizer.GetDoubleFromZeroToOne() < mutationRate)
                {
                    candidate.SetGene(i, !candidate.HasGene(i));
                }
            }

            return(candidate);
        }
        public (ICandidateSolution <ItemList> child1, ICandidateSolution <ItemList> child2) CrossOver(ICandidateSolution <ItemList> male, ICandidateSolution <ItemList> female, Knapsack input)
        {
            var child1 = male.Clone() as ICandidateSolution <ItemList>;
            var child2 = female.Clone() as ICandidateSolution <ItemList>;

            var items      = male.CandidateItem.Count;
            var crossPoint = input.Randomizer.IntLessThan(items);

            for (int i = 0; i < crossPoint; i++)
            {
                child1.SetGene(i, male.HasGene(i));
                child2.SetGene(i, female.HasGene(i));
            }

            for (int i = crossPoint; i < items; i++)
            {
                child1.SetGene(i, female.HasGene(i));
                child2.SetGene(i, male.HasGene(i));
            }

            return(child1, child2);
        }
 public (ICandidateSolution <ItemList> child1, ICandidateSolution <ItemList> child2) CrossOver(ICandidateSolution <ItemList> male, ICandidateSolution <ItemList> female)
 {
     return(CrossOver(male, female, null));
 }
        public T Run(TInput data)
        {
            CurrentGeneration = new List <ICandidateSolution <T> >(PopulationSize);
            for (int i = 0; i < PopulationSize; i++)
            {
                CurrentGeneration.Add(_generator.GenerateCandidate(data));
            }
            ICandidateSolution <T> bestSolution = null;
            int bestFitness = int.MinValue;

            var bestGen = 0;
            var gen     = 1;

            while (true)
            {
                var bestGenFitness = 0;
                var totalFitness   = 0;
                ICandidateSolution <T> bestSolutionThisGen = null;
                foreach (var candidateSolution in CurrentGeneration)
                {
                    candidateSolution.Repair();
                    totalFitness += candidateSolution.Fitness;
                    if (candidateSolution.Fitness > bestGenFitness)
                    {
                        bestGenFitness      = candidateSolution.Fitness;
                        bestSolutionThisGen = candidateSolution;
                    }
                }

                if (totalFitness > bestFitness)
                {
                    bestFitness  = totalFitness;
                    bestSolution = bestSolutionThisGen;
                    bestGen      = gen;
                }
                else
                {
                    if ((gen - bestGen) > MaxGenerationsWithNoChanges)
                    {
                        break;
                    }
                }
                var nextGen = new List <ICandidateSolution <T> >();
                while (nextGen.Count < PopulationSize)
                {
                    var parent1 = RouletteWheelSelectCandidate(totalFitness).CloneObject();
                    var parent2 = RouletteWheelSelectCandidate(totalFitness).CloneObject();
                    if (_randomizer.GetDoubleFromZeroToOne() < CrossOverRate)
                    {
                        var(child1, child2) = _generator.CrossOver(parent1, parent2, data);
                        parent1             = child1;
                        parent2             = child2;
                    }

                    if (_randomizer.GetDoubleFromZeroToOne() < MutationRate)
                    {
                        parent1 = _generator.Mutate(parent1, data, MutationRate);
                    }

                    if (_randomizer.GetDoubleFromZeroToOne() < MutationRate)
                    {
                        parent2 = _generator.Mutate(parent2, data, MutationRate);
                    }

                    nextGen.Add(parent1);
                    nextGen.Add(parent2);
                }

                gen++;
            }

            return(bestSolution?.CandidateItem);
        }