public void Evolve_ManyGenerations_Fast()
        {
            var selection = new EliteSelection();
            var crossover = new ThreeParentCrossover();
            var mutation = new UniformMutation(true);

            var fitness = new FunctionBuilderFitness(
                new FunctionBuilderInput(
                    new double[] { 1, 2, 3 },
                    6)
                ,
                new FunctionBuilderInput(
                    new double[] { 2, 3, 4 },
                    24)
            );
            var chromosome = new FunctionBuilderChromosome(fitness.AvailableOperations, 5);

            var population = new Population(100, 200, chromosome);

            var ga = new GeneticAlgorithm(population, fitness, selection, crossover, mutation);
            ga.Termination = new FitnessThresholdTermination(0);
            ga.Start();
            var bestChromosome = ga.BestChromosome as FunctionBuilderChromosome;
            Assert.AreEqual(0.0, bestChromosome.Fitness.Value);
            var actual = fitness.GetFunctionResult(
                             bestChromosome.BuildFunction(),
                             new FunctionBuilderInput(new double[] { 3, 4, 5 }, 60)
                );

            Assert.AreEqual(60.0, actual);
        }
        public void Cross_ThreeParents_OneChildren()
        {
            var chromosome1 = MockRepository.GenerateStub<ChromosomeBase>(4);
            chromosome1.ReplaceGenes(0, new Gene[]
            {
                new Gene(1),
                new Gene(2),
                new Gene(3),
                new Gene(4),
            });
            chromosome1.Expect(c => c.CreateNew()).Return(MockRepository.GenerateStub<ChromosomeBase>(4));

            var chromosome2 = MockRepository.GenerateStub<ChromosomeBase>(4);
            chromosome2.ReplaceGenes(0, new Gene[]
            {
                new Gene(1),
                new Gene(5),
                new Gene(6),
                new Gene(4)
            });
            chromosome2.Expect(c => c.CreateNew()).Return(MockRepository.GenerateStub<ChromosomeBase>(4));

            var chromosome3 = MockRepository.GenerateStub<ChromosomeBase>(4);
            chromosome3.ReplaceGenes(0, new Gene[]
            {
                new Gene(10),
                new Gene(11),
                new Gene(12),
                new Gene(13)
            });
            chromosome3.Expect(c => c.CreateNew()).Return(MockRepository.GenerateStub<ChromosomeBase>(4));

            var parents = new List<IChromosome>() { chromosome1, chromosome2, chromosome3 };

            var target = new ThreeParentCrossover();

            var actual = target.Cross(parents);
            Assert.AreEqual(1, actual.Count);
            Assert.AreEqual(4, actual[0].Length);

            Assert.AreEqual(1, actual[0].GetGene(0).Value);
            Assert.AreEqual(11, actual[0].GetGene(1).Value);
            Assert.AreEqual(12, actual[0].GetGene(2).Value);
            Assert.AreEqual(4, actual[0].GetGene(3).Value);
        }
        public void Start_ThreeParentCrossover_KeepsMinSizePopulation()
        {
            var selection = new EliteSelection();
            var crossover = new ThreeParentCrossover();
            var mutation = new UniformMutation();
            var chromosome = new ChromosomeStub();
            var target = new GeneticAlgorithm(new Population(100, 199, chromosome),
                    new FitnessStub() { SupportsParallel = false }, selection, crossover, mutation);

            target.Termination = new GenerationNumberTermination(100);

            target.Start();

            Assert.AreEqual(100, target.Population.Generations.Count);

            Assert.IsTrue(target.Population.Generations.All(g => g.Chromosomes.Count >= 100));
        }