public static Population GeneratePopulation(IRandom rand, int populationSize, int numberOfChromosomes, int geneLength, int minChromosomeLength, int maxChromosomeLength, List<Chromosome> geneBlacklist, List<Chromosome> geneWhitelist, Func<IOrganism, IOrganism> correctionFunction)
        {
            Population candidates = new Population();
            RandomChromosomeGenerator generator = new RandomChromosomeGenerator(rand, new ChromosomePart(rand) {
                GeneLength = geneLength,
                GeneBlacklist = geneBlacklist,
                GeneWhitelist = geneWhitelist,
                MinimumChromosomeLength = minChromosomeLength,
                MaximumChromosomeLegnth = maxChromosomeLength
            });

            for (int organismId = 0; organismId <= populationSize - 1; organismId++) {
                IOrganism organism = new Organism();
                for (int chromosomeId = 0; chromosomeId <= numberOfChromosomes - 1; chromosomeId++) {
                    organism.Chromosomes.Add(generator.GetChromosome());
                }

                if (correctionFunction != null) {
                    organism = correctionFunction(organism);
                }

                candidates.Add(organism);
            }

            return candidates;
        }
        public GeneticAlgorithm(IRandom rand, Population candidates, Func<IOrganism, double> fitnessFunction, ISelector selector, IMutator mutator, ICrossover crossLinker, double elitismProportion, int maximumGenerations)
        {
            this.rand = rand;
            this.candidates = candidates;
            this.fitnessFunction = fitnessFunction;
            this.selector = selector;
            this.mutator = mutator;
            this.crossLinker = crossLinker;
            this.elitismProportion = elitismProportion;
            this._generationCount = 0;
            this.generationInformation = new Dictionary<int, double>();
            this.initialCount = candidates.Count;
            this.maximumGenerations = maximumGenerations;

            this.candidates.CalculateFitnesses(this.fitnessFunction);
        }
        private void CreateNextGeneration()
        {
            Population nextGeneration = new Population();
            this.selector.SetCandidates(this.candidates);

            for (int i = 0; i <= Convert.ToInt32((this.candidates.Count / 2) * (1 - this.elitismProportion)) - 1; i++) {
                this.CreateOffspring(nextGeneration);
            }

            // Elitism involves bringing the top X% of the current into the next generation
            if (this.elitismProportion > 0) {
                int numberToKeep = Convert.ToInt32(this.elitismProportion * this.initialCount);
                this.candidates.GetBest(this.elitismProportion).ToList().ForEach(c => nextGeneration.Add(c));
            }

            this.candidates = nextGeneration;
            this.candidates.CalculateFitnesses(this.fitnessFunction);
            this.generationInformation.Add(this.GenerationCount, this.candidates.TotalFitness / this.candidates.Count);
            this._generationCount += 1;
        }
 public void SetCandidates(Population candidates)
 {
     this.candidates = candidates;
 }
        private void CreateOffspring(Population nextGeneration)
        {
            var parents = this.selector.PickCandidates(2).Take(2).ToList();
            var offspring = this.crossLinker.CrossLink(parents[0], parents[1]);
            this.mutator.Mutate(offspring.Item1);
            this.mutator.Mutate(offspring.Item2);

            if (this.encodingCorrector != null) {
                offspring = new Tuple<IOrganism, IOrganism>(this.encodingCorrector(offspring.Item1), this.encodingCorrector(offspring.Item2));
            }

            nextGeneration.Add(offspring.Item1);
            nextGeneration.Add(offspring.Item2);
        }
 public GeneticAlgorithm(IRandom rand, Population candidates, Func<IOrganism, double> fitnessFunction)
     : this(rand, candidates, fitnessFunction, new LinearRankingSelector(rand), new Mutator(rand, 0.05), new OnePointCrossover(rand, 0.7), 0.1, 15000)
 {
     this.mutator.AddMutator(new BitFlipMutation(rand));
 }