Пример #1
0
        // This function uses two fixed points for two-point crossover. For better performance these two points may be made random and/or adjusted over time
        // For example, in higher generations they could be moved further to the back
        public void twoFixedPointCrossover()
        {
            int    selectionSize = Convert.ToInt32(0.4 * populationSize);
            Genome parent1       = new Genome();
            Genome parent2       = new Genome();
            Genome child1        = new Genome();
            Genome child2        = new Genome();
            int    r;
            int    fixpoint1 = 4;
            int    fixpoint2 = 15;

            for (int i = selectionSize; i < populationSize; i++)
            {
                // Randomly selects first parent
                r       = Variables.getRandomInt(0, selectionSize);
                parent1 = oldPopulation[r].Genome;

                // Randomly selects second parent
                r       = Variables.getRandomInt(0, selectionSize);
                parent2 = oldPopulation[r].Genome;

                for (int j = 0; j < 20; j++)
                {
                    // Case 1: fixpoint 1 to fixpoint 2, fixpoints exclusive
                    if (j > fixpoint1 && j < fixpoint2)
                    {
                        // Iterates over the eight-bit-blocks and adds all bits to the respective parent
                        for (int k = j * 8; k < j * 8 + 8; k++)
                        {
                            child1.Genome1.Set(k, parent1.Genome1.Get(k));
                            child2.Genome1.Set(k, parent2.Genome1.Get(k));
                        }
                    }
                    // Case 2: Before fixpoint 1 and after fixpoint 2, fixpoints inclusive
                    else
                    {
                        // Iterates over the eight-bit-blocks and adds all bits to the respective parent
                        for (int k = j * 8; k < j * 8 + 8; k++)
                        {
                            child1.Genome1.Set(k, parent2.Genome1.Get(k));
                            child2.Genome1.Set(k, parent1.Genome1.Get(k));
                        }
                    }
                }

                Genome.genomeToPath(child1);
                population[i] = new Population(Variables.path, child1, 0, false, false);

                // Counts up since we are adding 2 children per iteration, not just one
                i++;

                // If we are not yet at maximum (which could happen due to double->int conversion) we add the second child too
                if (i < populationSize)
                {
                    Genome.genomeToPath(child2);
                    population[i] = new Population(Variables.path, child2, 0, false, false);
                }
            }
        }
Пример #2
0
        // This function uses single-bit Uniform Crossover.
        public void singleBitCrossover()
        {
            // Size of current new generation is 40% of old generation (before crossover)
            int    selectionSize = Convert.ToInt32(0.4 * populationSize);
            int    r;
            Genome parent1 = new Genome();
            Genome parent2 = new Genome();
            Genome mask    = new Genome();
            Genome child1  = new Genome();
            Genome child2  = new Genome();

            // Iterates from selection Size (current maximum of the new population) to population size, the wanted maximum. That means 60% come from crossover
            for (int i = selectionSize; i < populationSize; i++)
            {
                // Randomly selects first parent
                r       = Variables.getRandomInt(0, selectionSize);
                parent1 = oldPopulation[r].Genome;

                // Randomly selects second parent
                r       = Variables.getRandomInt(0, selectionSize);
                parent2 = oldPopulation[r].Genome;

                // Crates a random mask genome. This function sucks.
                mask = new Genome(true);

                // Generates children
                for (int j = 0; j < 160; j++)
                {
                    if (mask.Genome1.Get(j))
                    {
                        // If mask(i) is 1 then child1 gets the value at that point from parent1, child2 from parent2
                        child1.Genome1.Set(j, parent1.Genome1.Get(j));
                        child2.Genome1.Set(j, parent2.Genome1.Get(j));
                    }
                    else
                    {
                        // If mask(i) is 0 then child1 gets the value at that point from parent2, child2 from parent1
                        child1.Genome1.Set(j, parent2.Genome1.Get(j));
                        child2.Genome1.Set(j, parent1.Genome1.Get(j));
                    }
                }

                // Adds the genome and its corresponding path to the population at position i. Also sets Selected to false.
                Genome.genomeToPath(child1);
                population[i] = new Population(Variables.path, child1, 0, false, false);

                // Counts up since we are adding 2 children per iteration, not just one
                i++;

                // If we are not yet at maximum (which could happen due to double->int conversion) we add the second child too
                if (i < populationSize)
                {
                    Genome.genomeToPath(child2);
                    population[i] = new Population(Variables.path, child2, 0, false, false);
                }
            }
        }
Пример #3
0
        private void button_genomeToPath_Click(object sender, EventArgs e)
        {
            Genome genome = new Genome();

            char[] text = this.textBox1.Text.ToCharArray();

            for (int i = 0; i < 160; i++)
            {
                if (text[i] == '1')
                {
                    genome.Genome1.Set(i, true);
                }
            }

            Genome.genomeToPath(genome);
            this.glControl1.Refresh();
        }
Пример #4
0
        // This function uses genomePart Uniform Crossover. It works like a crossover function but uses a significantly shorter mask genome
        // because it always chooses an entire 8bit block
        public void eightBitCrossover()
        {
            // Size of current new generation is 40% of old generation (before crossover)
            int    selectionSize = Convert.ToInt32(0.4 * populationSize);
            int    r;
            Genome parent1 = new Genome();
            Genome parent2 = new Genome();

            bool[] mask;
            Genome child1 = new Genome();
            Genome child2 = new Genome();

            // Iterates from selection Size (current maximum of the new population) to population size, the wanted maximum. That means 60% come from crossover
            for (int i = selectionSize; i < populationSize; i++)
            {
                // Randomly selects first parent
                r       = Variables.getRandomInt(0, selectionSize);
                parent1 = oldPopulation[r].Genome;

                // Randomly selects second parent
                r       = Variables.getRandomInt(0, selectionSize);
                parent2 = oldPopulation[r].Genome;

                // Crates a random mask genome in form of a char[]. char[] is much faster than bool[], genome or bitarray and for our purpose the format doesn't matter
                mask = GenomePart.getRandomGenome();

                for (int j = 0; j < 20; j++)
                {
                    // Checks the mask
                    if (mask[j])
                    {
                        // If mask == 1 then the i'th 8bit block will be selected from parent1 for child1 and from parent2 for child2
                        // k = j*8 since every position in the mask genome covers 8 positions in the actual genome
                        for (int k = j * 8; k < j * 8 + 8; k++)
                        {
                            child1.Genome1.Set(k, parent1.Genome1.Get(k));
                            child2.Genome1.Set(k, parent2.Genome1.Get(k));
                        }
                    }
                    else
                    {
                        // If mask == 0 then the i'th 8bit block will be selected from parent1 for child2 and from parent2 for child1
                        // k = j*8 since every position in the mask genome covers 8 positions in the actual genome
                        for (int k = j * 8; k < j * 8 + 8; k++)
                        {
                            child1.Genome1.Set(k, parent2.Genome1.Get(k));
                            child2.Genome1.Set(k, parent1.Genome1.Get(k));
                        }
                    }
                }

                Genome.genomeToPath(child1);
                population[i] = new Population(Variables.path, child1, 0, false, false);

                // Counts up since we are adding 2 children per iteration, not just one
                i++;

                // If we are not yet at maximum (which could happen due to double->int conversion) we add the second child too
                if (i < populationSize)
                {
                    Genome.genomeToPath(child2);
                    population[i] = new Population(Variables.path, child2, 0, false, false);
                }
            }
        }