示例#1
0
        public void MutateThrowsErrorIfNoValidGenomesExist()
        {
            // Create genome builder that does not accept any genome.
            var genomeBuilder = GenomeBuilderTest.CreateCustomGenomeBuilder(
                mutationRate: 0,
                isValidFunction: candidate => false);
            // Build a genome.
            var genome = GenomeBuilderTest.BuildFittingGenome();

            // Mutate will try to repair the genome and should throw an exception as that will never work.
            Assert.Throws <TimeoutException>(() => genomeBuilder.Mutate(genome));
        }
示例#2
0
        public void MakeGenomeValidThrowsIfNoValidGenomeExists()
        {
            // Create genome builder that does not accept any genome.
            var genomeBuilder = GenomeBuilderTest.CreateCustomGenomeBuilder(
                mutationRate: 0,
                isValidFunction: candidate => false);

            // Try to repair a genome.
            var genome = GenomeBuilderTest.BuildFittingGenome();

            Assert.Throws <TimeoutException>(() => genomeBuilder.MakeGenomeValid(genome));
        }
示例#3
0
        public void MakeGenomeValidDoesNothingForValidGenome()
        {
            var genomeBuilder = GenomeBuilderTest.CreateGenomeBuilder();
            var genome        = GenomeBuilderTest.BuildFittingGenome();

            var originalGenome = new Genome(genome);

            genomeBuilder.MakeGenomeValid(genome);

            Assert.True(
                new Genome.GeneValueComparator().Equals(originalGenome, genome),
                $"Genome should not have changed from {originalGenome} to {genome}.");
        }
示例#4
0
        public void CrossoverWithEqualValuedGenomesGeneratesSameGenome()
        {
            var genomeBuilder = GenomeBuilderTest.CreateGenomeBuilder();

            // Create parents with equal gene values.
            var parent1 = GenomeBuilderTest.BuildFittingGenome();
            var parent2 = GenomeBuilderTest.BuildFittingGenome();

            // Do a crossover and check child's gene values.
            var child = genomeBuilder.Crossover(parent1, parent2);

            Assert.True(
                GenomeBuilderTest.genomeValueComparer.Equals(child, parent1),
                $"Crossover of equal valued genomes {parent1} and {parent2} produced child {child} with different values.");
        }
示例#5
0
        public void MutateMayChangeEveryParameter()
        {
            // Create genome builder with a mutation rate of 1.
            var configuration = new AlgorithmTunerConfiguration.AlgorithmTunerConfigurationBuilder()
                                .SetMutationRate(1)
                                .Build(maximumNumberParallelEvaluations: 1);
            var genomeBuilder = new GenomeBuilder(GenomeBuilderTest.BuildParameterTree(), configuration);

            // Create genome.
            var genome = GenomeBuilderTest.BuildFittingGenome();

            // Prepare structure to store which values have been mutated.
            string[] identifiers =
            {
                GenomeBuilderTest.DecisionParameter,
                GenomeBuilderTest.SmallValueParameter,
                GenomeBuilderTest.DiscreteParameter,
                GenomeBuilderTest.ContinuousParameter,
            };
            Dictionary <string, bool> hasBeenMutated = identifiers.ToDictionary(
                identifier => identifier,
                identifier => false);
            Dictionary <string, IAllele> originalValues = identifiers.ToDictionary(
                identifier => identifier,
                identifier => genome.GetGeneValue(identifier));

            // Do a lot of mutations.
            for (int i = 0; i < GenomeBuilderTest.loopCountForRandomTests; i++)
            {
                genomeBuilder.Mutate(genome);

                // After each one, check which genes have changed...
                foreach (string identifier in identifiers)
                {
                    bool valueChanged = !object.Equals(originalValues[identifier], genome.GetGeneValue(identifier));
                    if (valueChanged)
                    {
                        // ...and store them.
                        hasBeenMutated[identifier] = true;
                    }
                }
            }

            // Finally check that everything has been changed at least once.
            Assert.True(
                hasBeenMutated.All(keyValuePair => keyValuePair.Value),
                $"Genes {TestUtils.PrintList(hasBeenMutated.Where(keyValuePair => !keyValuePair.Value).Select(keyValuePair => keyValuePair.Key))} have not been mutated.");
        }
示例#6
0
        public void ValidateGenomeReturnsFalseForWrongType()
        {
            // Create a genome builder.
            var genomeBuilder = GenomeBuilderTest.CreateGenomeBuilder();

            // Create correct genome.
            var genome = GenomeBuilderTest.BuildFittingGenome();

            Assert.True(genomeBuilder.IsGenomeValid(genome));

            // Change a gene s.t. it has the wrong type.
            genome.SetGene(GenomeBuilderTest.DiscreteParameter, new Allele <double>(3));

            // Check method returns false now.
            Assert.False(
                genomeBuilder.IsGenomeValid(genome),
                $"Genome {genome} was evaluated as valid even if gene 'int' was created as double.");
        }
示例#7
0
        public void ValidateGenomeReturnsFalseForWrongDomain()
        {
            // Create a genome builder.
            var genomeBuilder = GenomeBuilderTest.CreateGenomeBuilder();

            // Create correct genome.
            var genome = GenomeBuilderTest.BuildFittingGenome();

            Assert.True(genomeBuilder.IsGenomeValid(genome));

            // Change a gene s.t. it is outside of domain.
            genome.SetGene(GenomeBuilderTest.ContinuousParameter, new Allele <double>(0.9));

            // Check method returns false now.
            Assert.False(
                genomeBuilder.IsGenomeValid(genome),
                $"Genome {genome} was evaluated as valid even if gene '{GenomeBuilderTest.ContinuousParameter}' was set to 0.9.");
        }
示例#8
0
        public void MakeGenomeValidRepairsInvalidGenome()
        {
            // Invalid genomes must exist. We forbid having a value of 3 for a certain gene.
            int forbiddenValue = 3;
            Func <Genome, bool> doesNotHave3ForInt1To5 = candidate =>
                                                         !object.Equals(candidate.GetGeneValue(GenomeBuilderTest.SmallValueParameter).GetValue(), forbiddenValue);

            // Create a genome builder implementing that check.
            var genomeBuilder = GenomeBuilderTest.CreateCustomGenomeBuilder(
                mutationRate: 0,
                isValidFunction: doesNotHave3ForInt1To5);

            var genome = GenomeBuilderTest.BuildFittingGenome();

            genome.SetGene(GenomeBuilderTest.SmallValueParameter, new Allele <int>(forbiddenValue));

            genomeBuilder.MakeGenomeValid(genome);
            Assert.True(genomeBuilder.IsGenomeValid(genome), $"{genome} should be valid after repairing it.");
        }
示例#9
0
        public void MutateChangesGivenGenomeIfMutationRateIs1()
        {
            // Create genome builder with a mutation rate of 1.
            var configuration =
                new AlgorithmTunerConfiguration.AlgorithmTunerConfigurationBuilder()
                .SetMutationRate(1)
                .Build(maximumNumberParallelEvaluations: 1);
            var genomeBuilder = new GenomeBuilder(GenomeBuilderTest.BuildParameterTree(), configuration);

            // Build a fitting genome and store original description.
            var    genome = GenomeBuilderTest.BuildFittingGenome();
            string originalDescription = genome.ToString();

            // Call mutate and check genome changed.
            genomeBuilder.Mutate(genome);
            Assert.NotEqual(
                originalDescription,
                genome.ToString());
        }
示例#10
0
        public void MutateIsNoOperationIfMutationRateIs0()
        {
            // Create genome builder with a mutation rate of 0.
            var genomeBuilder = GenomeBuilderTest.CreateGenomeBuilderWithoutRandomMutation();

            // Build a fitting genome and store original description.
            var    genome = GenomeBuilderTest.BuildFittingGenome();
            string originalDescription = genome.ToString();

            // Check many times:
            for (int i = 0; i < GenomeBuilderTest.loopCountForRandomTests; i++)
            {
                // If mutate is called, the genome does not change.
                genomeBuilder.Mutate(genome);
                Assert.Equal(
                    originalDescription,
                    genome.ToString());
            }
        }
示例#11
0
        public void MutateRespectsMutationRate()
        {
            // Create genome builder with a mutation rate of 0.35.
            double mutationRate  = 0.35;
            var    configuration =
                new AlgorithmTunerConfiguration.AlgorithmTunerConfigurationBuilder()
                .SetMutationRate(mutationRate)
                .Build(maximumNumberParallelEvaluations: 1);
            var genomeBuilder = new GenomeBuilder(GenomeBuilderTest.BuildParameterTree(), configuration);

            // Create genome.
            var genome = GenomeBuilderTest.BuildFittingGenome();

            // For a lot of iterations:
            IAllele oldGeneValue = genome.GetGeneValue(GenomeBuilderTest.ContinuousParameter);
            int     changeCount  = 0;
            int     numberLoops  = 1000;

            for (int i = 0; i < numberLoops; i++)
            {
                // Mutate the genome ...
                genomeBuilder.Mutate(genome);
                // ... compare the continuous parameter gene...
                IAllele newGeneValue = genome.GetGeneValue(GenomeBuilderTest.ContinuousParameter);
                if (!object.Equals(newGeneValue, oldGeneValue))
                {
                    changeCount++;
                }

                // ... and count the number of times it changes.
                oldGeneValue = newGeneValue;
            }

            // Finally compare the number of mutations with the expected number.
            double expectedNumberMutations = mutationRate * numberLoops;

            Assert.True(
                Math.Abs(expectedNumberMutations - changeCount) <= 0.1 * expectedNumberMutations,
                "Number of mutations was not as expected.");
        }
示例#12
0
        public void MutateRepairsInvalidGenomes()
        {
            // Invalid genomes must exist. We forbid having a value of 3 for a certain gene.
            int forbiddenValue = 3;
            Func <Genome, bool> doesNotHave3ForInt1To5 = candidate =>
                                                         !object.Equals(candidate.GetGeneValue(GenomeBuilderTest.SmallValueParameter).GetValue(), forbiddenValue);

            // Create a genome builder implementing that check. It also should never mutate randomly
            // so we can be sure the repair was not due to the mutation itself.
            var genomeBuilder = GenomeBuilderTest.CreateCustomGenomeBuilder(
                mutationRate: 0,
                isValidFunction: doesNotHave3ForInt1To5);

            // Build an invalid genome.
            var genome = GenomeBuilderTest.BuildFittingGenome();

            genome.SetGene(GenomeBuilderTest.SmallValueParameter, new Allele <int>(forbiddenValue));

            // Mutate and check the broken gene was fixed.
            genomeBuilder.Mutate(genome);
            Assert.NotEqual(
                forbiddenValue,
                genome.GetGeneValue(GenomeBuilderTest.SmallValueParameter).GetValue());
        }