0

I have implemented a one point crossover as follows;

public void onePointCrossover(Individual indi) {
    if (SGA.rand.nextDouble() < pc) {

        int xoverpoint = SGA.rand.nextInt(length);


        int tmp;
        for (int i=xoverpoint; i<length; i++){
            tmp = chromosome[i];
            chromosome[i] = indi.chromosome[i];
            indi.chromosome[i] = tmp;
        }   
    }   
}

One point crossover - crossover point is selected, binary string from beginning of chromosome to the crossover point is copied from one parent, the rest is copied from the second parent.

Parent 1 = chromosome and Parent 2 = indi.

I am turning the parents into children inplace.

I now need to also do a two point crossover but having some trouble, this is what I have so far but I believe the bottom half of the code is doing the same thing as a one point crossover rather than swapping the middle sections.

       public void twoPointCrossover(Individual indi) {
        if (SGA.rand.nextDouble() < pc) {

            int xoverpoint = SGA.rand.nextInt(length);
            int xoverpoint2 = SGA.rand.nextInt(length);



            int tmp;

            if (xoverpoint > xoverpoint2){
                tmp = xoverpoint;
                xoverpoint = xoverpoint2;
                xoverpoint2 = tmp;
            }

            for (int i=xoverpoint; i<xoverpoint2; i++){
                tmp = chromosome[i];
                chromosome[i] = indi.chromosome[i];
                indi.chromosome[i] = tmp;
            }   
        }   
    }
}

This does not seem right and any help will be appreciated so much! Thanks!

manlio
  • 18,345
  • 14
  • 76
  • 126
Student
  • 443
  • 1
  • 7
  • 11
  • What are you expecting to happen? This isn't a complete example so any help you would get is likely to be guesswork. – wkl Feb 16 '12 at 14:29
  • Why do you think that this does not seem right? What are you getting, what are you expecting? – npinti Feb 16 '12 at 14:29
  • All I did was add the middle section to the original one point crossover, the rest is the same. It does not give any errors but I dont think it is doing a two point crossover either? – Student Feb 16 '12 at 14:41
  • This is what is meant to happened - two crossover point are selected, binary string from beginning of chromosome to the first crossover point is copied from one parent, the part from the first to the second crossover point is copied from the second parent and the rest is copied from the first parent. My first parent is chromosome and second parent is indi.chromosome. Shouldnt I assign xoverpoint2 = j ? and then use it like chromosom[j] and etc? – Student Feb 16 '12 at 14:45

2 Answers2

1

You should check for i < (or <=) xoverpoint2 rather than i<length in the loop.

Alexander Pavlov
  • 31,598
  • 5
  • 67
  • 93
  • This is what is meant to happened - two crossover point are selected, binary string from beginning of chromosome to the first crossover point is copied from one parent, the part from the first to the second crossover point is copied from the second parent and the rest is copied from the first parent. My first parent is chromosome and second parent is indi.chromosome. Shouldnt I assign xoverpoint2 = j ? and then use it like chromosom[j] and etc? – Student Feb 16 '12 at 14:39
  • That makes more sense. So, I believe you turn your parents into children inplace, and then my solution above should work as expected: you swap the middle parts of two chromosomes, which is essentially what you want to do. – Alexander Pavlov Feb 16 '12 at 14:55
  • Yes I have added your solution above but I believe I am still performing a one point crossover as the results are exactly the same as a one point crossover. Yes that's exactly what I want to do swap the middle parts, but I don't know how to do that. – Student Feb 16 '12 at 15:00
  • For e.g. chromosome[i] would mean beginning of parent 1 to 1st crosover point but I don't know how to refer to the middle part of the so crossover points? Appreciate your help – Student Feb 16 '12 at 15:01
  • This part is performing a one point crossover; for (int i=xoverpoint; i – Student Feb 16 '12 at 15:03
  • Why do you think that your altered solution does something different than what you expect? Perhaps your mutation rate or population size are not high enough for the mutations to take qualitative effect? Do you have a unit-test for the `twoPointCrossover()` method? Definitely, to perform a 2-point Xover, you need to swap only the middle parts of the chromosomes (from `xoverpoint` to `xoverpoint2`), that's it. – Alexander Pavlov Feb 16 '12 at 15:04
  • I understand where your coming from, I will now try testing again with different values, but it seems like I am not referring to my second crossover point and instead just referred to first crossover point [i] like in one point crossover. I cant see the bit where the middle of each parent is swapped and rather looks like the beginning and end of each parent is swapped. Looking at the code can you say it is performing a 2 point crossover? – Student Feb 16 '12 at 15:09
  • Did you rewrite your loop as `for (int i=xoverpoint; i – Alexander Pavlov Feb 16 '12 at 15:23
  • Alexander is it possible to email you the document I am working from? I can see you know about genetic algorithms and once you look at it things will be much clearer – Student Feb 16 '12 at 15:28
  • Good. Now both of your boundaries are random, not just one. I believe it's a 2-point crossover. Try coming up with a unit-test for that. – Alexander Pavlov Feb 16 '12 at 15:29
  • I increased my population but there was no change. My mutation rate was 0.01 and when I change it to 0.2 or above then I started to see a difference between one point and two point crossover. Thank you so much Alexander. Can't thank you enough! – Student Feb 16 '12 at 15:40
0

I'm working on the same problem now. Here is my solution:

// Two-Point Crossover function
public Genome twoPtCrossover(Genome partner) {
    Genome child = new Genome(partner.genome.length);

    int crosspoint1 = xd.nextInt(genome.length);
    int crosspoint2 = xd.nextInt(genome.length);

    // Ensure crosspoints are different...
    if (crosspoint1 == crosspoint2){
        if(crosspoint1 == 0){
            crosspoint2++;
        } else {
            crosspoint1--;
        }
    }
    // .. and crosspoint1 is lower than crosspoint2
    if (crosspoint2 < crosspoint1) {
        int temp = crosspoint1;
        crosspoint1 = crosspoint2;
        crosspoint2 = temp;
    }

    for (int i = 0; i < genome.length; i++) {
        if (i < crosspoint1 || i > crosspoint2)
            child.genome[i] = genome[i];
        else
            child.genome[i] = partner.genome[i];
    }
    return child;
}
old_dd
  • 135
  • 2
  • 13