Exemple #1
0
        public void CrossoverRandomlyDecidesOnParentToTakeGeneValueFromForSingleGene()
        {
            // Build genome builder with a parameter tree that consists of a single continuous parameter.
            string         parameterName = "parameter";
            IParameterNode parameter     = new ValueNode <double>(parameterName, new ContinuousDomain());
            var            genomeBuilder = new GenomeBuilder(
                new ParameterTree(parameter),
                new AlgorithmTunerConfiguration.AlgorithmTunerConfigurationBuilder().Build(maximumNumberParallelEvaluations: 1));

            // Build genomes with different parameter values.
            var             parent1       = new Genome();
            var             parent2       = new Genome();
            Allele <double> parent1Allele = new Allele <double>(0);
            Allele <double> parent2Allele = new Allele <double>(1);

            parent1.SetGene(parameterName, parent1Allele);
            parent2.SetGene(parameterName, parent2Allele);

            // Observe what gene value the children's genes have.
            int numberLoops = 1000;
            int observedInheritanceFromParent1 = 0;

            for (int i = 0; i < numberLoops; i++)
            {
                var child = genomeBuilder.Crossover(parent1, parent2);
                if (object.Equals(parent1Allele, child.GetGeneValue(parameterName)))
                {
                    observedInheritanceFromParent1++;
                }
            }

            double[] observed = { observedInheritanceFromParent1, numberLoops - observedInheritanceFromParent1 };

            // We would expect each value the same number of times:
            double[] expected = { numberLoops / 2, numberLoops / 2 };

            // Use Chi-Squared Test.
            var equalProbabilityTest = new ChiSquareTest(expected, observed, degreesOfFreedom: numberLoops - 1);

            Assert.False(
                equalProbabilityTest.Significant,
                $"Single gene was found to be not equally distributed in crossovers by the Chi-Squared test with significance level of {equalProbabilityTest.Size}.");
        }
Exemple #2
0
        public void CrossoverRespectsSwitchProbability()
        {
            // Build parameter tree that consists of two dependent continuous parameters.
            string rootParameterName  = "parameterRoot";
            string childParameterName = "parameterChild";
            var    rootParameter      = new ValueNode <double>(rootParameterName, new ContinuousDomain());
            var    childParameter     = new ValueNode <double>(childParameterName, new ContinuousDomain());

            rootParameter.SetChild(childParameter);

            // Build genome builder with that parameter tree and a specific crossover switch probability.
            double crossoverSwitchParameter    = 0.25;
            AlgorithmTunerConfiguration config = new AlgorithmTunerConfiguration.AlgorithmTunerConfigurationBuilder()
                                                 .SetCrossoverSwitchProbability(crossoverSwitchParameter)
                                                 .Build(maximumNumberParallelEvaluations: 1);
            var genomeBuilder = new GenomeBuilder(new ParameterTree(rootParameter), config);

            // Build parents.
            var parent1            = new Genome();
            var parent2            = new Genome();
            var parent1RootAllele  = new Allele <double>(1);
            var parent1ChildAllele = new Allele <double>(2);
            var parent2RootAllele  = new Allele <double>(3);
            var parent2ChildAllele = new Allele <double>(4);

            parent1.SetGene(rootParameterName, parent1RootAllele);
            parent1.SetGene(childParameterName, parent1ChildAllele);
            parent2.SetGene(rootParameterName, parent2RootAllele);
            parent2.SetGene(childParameterName, parent2ChildAllele);

            // Observe if children's genes come from the same parent or not.
            int numberLoops             = 1000;
            int genesCameFromSameParent = 0;

            for (int i = 0; i < numberLoops; i++)
            {
                var     child       = genomeBuilder.Crossover(parent1, parent2);
                IAllele rootAllele  = child.GetGeneValue(rootParameterName);
                IAllele childAllele = child.GetGeneValue(childParameterName);
                bool    geneValuesInheritedFromSameParent =
                    (object.Equals(rootAllele, parent1RootAllele) && object.Equals(childAllele, parent1ChildAllele)) ||
                    (object.Equals(rootAllele, parent2RootAllele) && object.Equals(childAllele, parent2ChildAllele));
                if (geneValuesInheritedFromSameParent)
                {
                    genesCameFromSameParent++;
                }
            }

            double[] observed = { genesCameFromSameParent, numberLoops - genesCameFromSameParent };

            // We would expect each case according to switch probability:
            int expectedSwitches = (int)(crossoverSwitchParameter * numberLoops);

            double[] expected = { numberLoops - expectedSwitches, expectedSwitches };

            // Use Chi-Squared Test.
            var matchesSwitchProbabilityTest = new ChiSquareTest(expected, observed, degreesOfFreedom: numberLoops - 1);

            Assert.False(
                matchesSwitchProbabilityTest.Significant,
                $"Crossover was found not to respect the switch probability by the Chi-Squared test with significance level of {matchesSwitchProbabilityTest.Size}.");
        }