Double array chromosome.

Double array chromosome represents array of double values. Array length is in the range of [2, 65536].

See documentation to Mutate and Crossover methods for information regarding implemented mutation and crossover operators.

Inheritance: ChromosomeBase
Ejemplo n.º 1
1
        /// <summary>
        /// Initializes a new instance of the <see cref="DoubleArrayChromosome"/> class.
        /// </summary>
        /// 
        /// <param name="source">Source chromosome to copy.</param>
        /// 
        /// <remarks><para>This is a copy constructor, which creates the exact copy
        /// of specified chromosome.</para></remarks>
        /// 
        public DoubleArrayChromosome(DoubleArrayChromosome source)
        {
            this.chromosomeGenerator = source.chromosomeGenerator;
            this.mutationMultiplierGenerator = source.mutationMultiplierGenerator;
            this.mutationAdditionGenerator = source.mutationAdditionGenerator;
            this.length = source.length;
            this.fitness = source.fitness;
            this.mutationBalancer = source.mutationBalancer;
            this.crossoverBalancer = source.crossoverBalancer;

            // copy genes
            val = (double[])source.val.Clone();
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Create new random chromosome with same parameters (factory method).
        /// </summary>
        ///
        /// <remarks><para>The method creates new chromosome of the same type, but randomly
        /// initialized. The method is useful as factory method for those classes, which work
        /// with chromosome's interface, but not with particular chromosome type.</para></remarks>
        ///
        public override IChromosome CreateNew()
        {
            var chromosome = new DoubleArrayChromosome(chromosomeGenerator, mutationMultiplierGenerator, mutationAdditionGenerator, length);

            chromosome.CrossoverBalancer = this.CrossoverBalancer;
            chromosome.MutationBalancer  = this.MutationBalancer;

            return(chromosome);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="DoubleArrayChromosome"/> class.
        /// </summary>
        ///
        /// <param name="source">Source chromosome to copy.</param>
        ///
        /// <remarks><para>This is a copy constructor, which creates the exact copy
        /// of specified chromosome.</para></remarks>
        ///
        public DoubleArrayChromosome(DoubleArrayChromosome source)
        {
            this.chromosomeGenerator         = source.chromosomeGenerator;
            this.mutationMultiplierGenerator = source.mutationMultiplierGenerator;
            this.mutationAdditionGenerator   = source.mutationAdditionGenerator;
            this.length            = source.length;
            this.fitness           = source.fitness;
            this.mutationBalancer  = source.mutationBalancer;
            this.crossoverBalancer = source.crossoverBalancer;

            // copy genes
            val = (double[])source.val.Clone();
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Crossover operator.
        /// </summary>
        ///
        /// <param name="pair">Pair chromosome to crossover with.</param>
        ///
        /// <remarks><para>The method performs crossover between two chromosomes, selecting
        /// randomly the exact type of crossover to perform, which depends on <see cref="CrossoverBalancer"/>.
        /// Before crossover is done a random number is generated in [0, 1] range - if the
        /// random number is smaller than <see cref="CrossoverBalancer"/>, then the first crossover
        /// type is used, otherwise second type is used.</para>
        ///
        /// <para>The <b>first crossover type</b> is based on interchanging
        /// range of genes (array elements) between these chromosomes and is known
        /// as one point crossover. A crossover point is selected randomly and chromosomes
        /// interchange genes, which start from the selected point.</para>
        ///
        /// <para>The <b>second crossover type</b> is aimed to produce one child, which genes'
        /// values are between corresponding genes of parents, and another child, which genes'
        /// values are outside of the range formed by corresponding genes of parents.
        /// Let take, for example, two genes with 1.0 and 3.0 valueû (of course chromosomes have
        /// more genes, but for simplicity lets think about one). First of all we randomly choose
        /// a factor in the [0, 1] range, let's take 0.4. Then, for each pair of genes (we have
        /// one pair) we calculate difference value, which is 2.0 in our case. In the result we’ll
        /// have two children – one between and one outside of the range formed by parents genes' values.
        /// We may have 1.8 and 3.8 children, or we may have 0.2 and 2.2 children. As we can see
        /// we add/subtract (chosen randomly) <i>difference * factor</i>. So, this gives us exploration
        /// in between and in near outside. The randomly chosen factor is applied to all genes
        /// of the chromosomes participating in crossover.</para>
        /// </remarks>
        ///
        public override void Crossover(IChromosome pair)
        {
            DoubleArrayChromosome p = (DoubleArrayChromosome)pair;
            var rand = Generator.Random;

            // check for correct pair
            if ((p != null) && (p.length == length))
            {
                if (rand.NextDouble() < crossoverBalancer)
                {
                    // crossover point
                    int crossOverPoint = rand.Next(length - 1) + 1;
                    // length of chromosome to be crossed
                    int crossOverLength = length - crossOverPoint;
                    // temporary array
                    double[] temp = new double[crossOverLength];

                    // copy part of first (this) chromosome to temp
                    Array.Copy(val, crossOverPoint, temp, 0, crossOverLength);
                    // copy part of second (pair) chromosome to the first
                    Array.Copy(p.val, crossOverPoint, val, crossOverPoint, crossOverLength);
                    // copy temp to the second
                    Array.Copy(temp, 0, p.val, crossOverPoint, crossOverLength);
                }
                else
                {
                    double[] pairVal = p.val;

                    double factor = rand.NextDouble();
                    if (rand.Next(2) == 0)
                    {
                        factor = -factor;
                    }

                    for (int i = 0; i < length; i++)
                    {
                        double portion = (val[i] - pairVal[i]) * factor;

                        val[i]     -= portion;
                        pairVal[i] += portion;
                    }
                }
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Runs learning epoch.
        /// </summary>
        /// 
        /// <param name="input">Array of input vectors.</param>
        /// <param name="output">Array of output vectors.</param>
        /// 
        /// <returns>Returns summary squared learning error for the entire epoch.</returns>
        /// 
        /// <remarks><para><note>While running the neural network's learning process, it is required to
        /// pass the same <paramref name="input"/> and <paramref name="output"/> values for each
        /// epoch. On the very first run of the method it will initialize evolutionary fitness
        /// function with the given input/output. So, changing input/output in middle of the learning
        /// process, will break it.</note></para></remarks>
        ///
        public double RunEpoch(double[][] input, double[][] output)
        {
            Debug.Assert(input.Length > 0);
            Debug.Assert(output.Length > 0);
            Debug.Assert(input.Length == output.Length);
            Debug.Assert(network.InputsCount == input.Length);

            // check if it is a first run and create population if so
            if (population == null)
            {
                // sample chromosome
                DoubleArrayChromosome chromosomeExample = new DoubleArrayChromosome(
                    chromosomeGenerator, mutationMultiplierGenerator, mutationAdditionGenerator,
                    numberOfNetworksWeights);

                // create population ...
                population = new Population(populationSize, chromosomeExample,
                    new EvolutionaryFitness(network, input, output), selectionMethod);
                // ... and configure it
                population.CrossoverRate = crossOverRate;
                population.MutationRate = mutationRate;
                population.RandomSelectionPortion = randomSelectionRate;
            }

            // run genetic epoch
            population.RunEpoch();

            // get best chromosome of the population
            DoubleArrayChromosome chromosome = (DoubleArrayChromosome)population.BestChromosome;
            double[] chromosomeGenes = chromosome.Value;

            // put best chromosome's value into neural network's weights
            int v = 0;

            for (int i = 0; i < network.Layers.Length; i++)
            {
                Layer layer = network.Layers[i];

                for (int j = 0; j < layer.Neurons.Length; j++)
                {
                    ActivationNeuron neuron = layer.Neurons[j] as ActivationNeuron;

                    for (int k = 0; k < neuron.Weights.Length; k++)
                    {
                        neuron.Weights[k] = chromosomeGenes[v++];
                    }
                    neuron.Threshold = chromosomeGenes[v++];
                }
            }

            Debug.Assert(v == numberOfNetworksWeights);

            return 1.0 / chromosome.Fitness;
        }