2

What is the best way to implement two point crossover in Matlab? The two point crossover is described here. Note that in my application I cannot split the lists wherever. They are grouped by four, so places where it is allowed to split a list (chromosome) is 4, 8, 12 and so on (this is because my application is a linear genetic programming problem).

I tried this, but it doesn't work as sometimes I get chromosomes that have a number of elements which is not evenly divisible by four. I need help figuring out how to make it work.

function newPopulation = Crossover( population, p )

newPopulation = population;

for i=1:2:length(population)
    if p < rand
        [newPopulation{i}, newPopulation{i+1}] = PerformCrossover( newPopulation{i}, newPopulation{i+1} );
    end
end

end

function [newChromosome1, newChromosome2] = PerformCrossover( c1, c2 )
    l1 = length(c1)/4;
    l2 = length(c2)/4;

    i1 = 4*sort( randperm( l1, 2 ) )-[3 4];
    i2 = 4*sort( randperm( l2, 2 ) )-[3 4];

    newChromosome1 = [ c1( 1:l1<i1(1) ) c2( i2(1):i2(2) ) c1( 1:l1>i1(2) ) ];
    newChromosome2 = [ c2( 1:l2<i2(1) ) c1( i1(1):i1(2) ) c2( 1:l2>i2(2) ) ];
end

EDIT. There seems to be confusion. I want the version of crossover that is described by my code. In this code the segments from each chromosome do not have the same length. This means that I change the size of the chromosomes when I do the swap, this is intended. Further explanation is available in the comment to McMa.

manlio
  • 18,345
  • 14
  • 76
  • 126
C. E.
  • 10,297
  • 10
  • 53
  • 77
  • random numbers are quite cheap to generate. Why not generate the first random number through round(rand(1)*length(chromosomeLength)/4)*4, and then generate a second one through the same formula and checking if it is equal to the past one? – ASantosRibeiro Oct 13 '14 at 08:56
  • @ASantosRibeiro Why would that be better than what I am currently doing? – C. E. Oct 13 '14 at 09:29
  • It is exactly the same (same random generator and same ideology), just a different way, as I do not understand your problem as that is already optimized. – ASantosRibeiro Oct 13 '14 at 13:02
  • Further the problem seems not to be with optimization but your code seems incorrect when you create the "newChromosome1" and "newChromosome2" – ASantosRibeiro Oct 13 '14 at 13:09

3 Answers3

2

leave everything as is, as it is already optimized, and correct this:

i1 = 4*sort( randperm( l1, 2 ) )-[3 3];
i2 = 4*sort( randperm( l2, 2 ) )-[3 3];

newChromosome1 = [ c1( 1:i1(1) ) c2( i2(1)+1:i2(2)-1 ) c1( i1(2):end ) ];
newChromosome2 = [ c2( 1:i2(1) ) c1( i1(1)+1:i1(2)-1 ) c2( i2(2):end ) ];
ASantosRibeiro
  • 1,247
  • 8
  • 15
0

I am not sure if you correctly understand the randperm function. Also, the 2-point crossover is not generally restricted to chromosomes of length divisible by 4.

The easiest way IMHO is to draw two random numbers that define your crossover points and exist in the range [1, chromosomeLength]. Than just simply swap the information between these points. I don't think you need a randperm function...

% use randi(n) that gives a random integer in the range [0,n]
% create the first crossover point pos1 in the interval [1, chromosomelength-1]
% create the second crossover point pos2 in the interval [pos1+1, chromosomeLength)]

newChromosome1 = [ c1( 1 : pos1-1 ) ) c2( pos1 : pos2-1 ) c1( pos2 : chromosomeLength ) ];
newChromosome2 = [ c2( 1 : pos1-1 ) ) c1( pos1 : pos2-1 ) c2( pos2 : chromosomeLength ) ];

additionally you might handle the case that pos1 gets the value 1, since c1( 1 : 1-1 ) would cause an exception

  • Genetic algorithms are used for many things. In this case it's a linear genetic programming problem, where a sequence of four genes encode an "instruction". The first gene is an operator, the second a destination register, the third and fourth are operands. I can't split up an instruction, therefore I need the crossover points to lie on 4, 8, 12 etc. I am using randperm to get two unique numbers in the interval. If I use randi I might get two of the same. And the exceptions are a big problem; you are avoiding all the hard stuff.... – C. E. Oct 13 '14 at 07:38
  • OK, I have not seen that this is a genetic programming problem. In this case, it makes sense that you exchange complete instruction sets rather than single bits... sorry, my fault. – Stephan Hutterer Oct 13 '14 at 08:40
0

Using single randperm() without mixing parameters should work:

function [newChromosome1, newChromosome2] = PerformCrossover( c1, c2 )

    len=floor(min(length(c1),length(c2))/4);

    xOver=4*sort(randperm(len,2));

    newChromosome1=[c1(1:xOver(1)),c2(xOver(1)+1:xOver(2)),c1(xOver(2)+1:end)];
    newChromosome2=[c2(1:xOver(1)),c1(xOver(1)+1:xOver(2)),c2(xOver(2)+1:end)];
end

That would be a 2-point crossover of segments that are divisible by 4.

Additionaly xOver=4*sort(randperm(len-1,2)); will rule out the chance of randperm() returning the maximum value of len which would result in only a 1-point crossover for the smaller vector

McMa
  • 1,568
  • 7
  • 22
  • There is no reason to select the shortest length. Then it will never pick elements from the end of the longer chromosome. It is also not necessary to use `floor` since chromosomes are always divisible by four, since they encode instructions with that number of components. This is also not correct because you pick the same segments from both chromosomes. Different segments should be picked from the different chromosomes, and then they are swapped. – C. E. Oct 13 '14 at 11:02
  • N-point crossovers in vectors of different length will always leave the difference between them two unchanged, because they have no correspondence to be crossed-over. If that's a problem you will have to chose a different approach to recombination :/ – McMa Oct 13 '14 at 11:11
  • You are wrong. I have a book in front of me that supports my version of crossover. There are many versions of N-point crossover, but I have made it clear which one I want. – C. E. Oct 13 '14 at 11:13
  • My understanding of n-point crossover does not allow for this, but if you mind sharing the part of the book, my code should be easy to adapt for it. – McMa Oct 13 '14 at 11:20
  • I think it will help if you read my code, as it does what I am trying to do more or less. Let's say I take out element 5 to 7 in chromosome 1. Then I take out element 3 to 9 in chromosome 2. Then I put these six element in between element 4 and 8 in chromosome 1. Then I take the elements from chromosome 1 and put them into chromosome 2 between the old elements 2 and 10. The total length of the chromosomes adapt to the changing length, so what was element 8 in chromosome 1 is now element 11. – C. E. Oct 13 '14 at 11:29