Reputation: 33
I'm trying to learn about genetic algorithms and am currently working on "crossing over" two "genes". A gene is an integer array, consisting of ones and zeros. To exemplify my problem let's say we have two genes.
int[] geneA = {1,0,0,0,0};
int[] geneB = {0,1,1,1,0};
The expected result from a cross-over, for example at position 3 would be:
geneA = [1,0,0,1,0]
geneB = [0,1,1,0,0]
Meaning that every element at the index of 3 or above would be swapped with the equivalent element of the other gene. To achieve this I wrote the following method:
private void crossOver(int[] geneA, int[] geneB, int pos) {
int copyA[];
int copyB[];
copyA = geneA;
copyB = geneB;
for(int i = pos; i < geneA.length; i++) {
geneA[i] = copyB[i];
geneB[i] = copyA[i];
}
System.out.println(Arrays.toString(geneA);
System.out.println(Arrays.toString(geneB);
}
However, it seems that the elements of geneB simply get copied into geneA at the index of 3 or higher. The console output is as following:
[1, 0, 0, 1, 0]
[0, 1, 1, 1, 0]
Any explanations or help are highly appreciated. Thanks in advance!
Upvotes: 2
Views: 1283
Reputation: 159155
copyA = geneA
does not create a copy. Both variables now refer to the same array.
There is no need to waste time and space on copying the entire array.
When you swap values, you just need to store one of the values in a temporary variable.
private static void crossOver(int[] geneA, int[] geneB, int pos) {
for (int i = pos; i < geneA.length; i++) {
int temp = geneA[i];
geneA[i] = geneB[i];
geneB[i] = temp;
}
}
That will update the arrays in-place, so the caller will see the change.
int[] geneA = {1,0,0,0,0};
int[] geneB = {0,1,1,1,0};
crossOver(geneA, geneB, 3);
System.out.println(Arrays.toString(geneA));
System.out.println(Arrays.toString(geneB));
Output
[1, 0, 0, 1, 0]
[0, 1, 1, 0, 0]
Upvotes: 4
Reputation: 10717
This code will work:
void crossOver(int[] geneA, int[] geneB, int pos) {
int copyA[];
int copyB[];
copyA = Arrays.copyOf(geneA,geneA.length);
copyB = Arrays.copyOf(geneB,geneB.length);
for(int i = pos; i < geneA.length; i++) {
geneA[i] = copyB[i];
geneB[i] = copyA[i];
}
System.out.println(Arrays.toString(geneA));
System.out.println(Arrays.toString(geneB));
}
Problem with your code was that you was doing copy of array by:
copyA = geneA;
copyB = geneB;
which just pointed to the same reference. So in the rest of the code you was working on the same array, instead of working on a copy.
Instead proper way of copying arrays is:
copyA = Arrays.copyOf(geneA,geneA.length);
copyB = Arrays.copyOf(geneB,geneB.length);
Upvotes: 1
Reputation: 1923
There is problem. you copy both array very easy to copyA
and copyB
which doesn't make a new copy. it just copy reference of array and both array refer to same memory. so any change in one of them will change other too. for this you can use Arrays.copyof()
instead.
I think this is what you want:
private void crossOver(int[] geneA, int[] geneB, int pos) {
int[] copyA = Arrays.copyOf(geneA, geneA.length);
int[] copyB = Arrays.copyOf(geneB, geneB.length);
for(int i = pos; i < geneA.length; i++) {
geneA[i] = copyB[i];
geneB[i] = copyA[i];
}
System.out.println(Arrays.toString(geneA));
System.out.println(Arrays.toString(geneB));
}
instead of that, as I see, you change geneA
and geneB
after making copy and swapping, so I think this code will do same with less code but I don't know this is what you want or not:
private void crossOver(int[] geneA, int[] geneB, int pos) {
for(int i = pos; i < geneA.length; i++) {
int temp = geneA[i];
geneA[i] = geneB[i];
geneB[i] = temp;
}
System.out.println(Arrays.toString(geneA));
System.out.println(Arrays.toString(geneB));
}
I hope this help you.
Upvotes: 1
Reputation: 1410
I think you are going wrong when you create copies of the arrays ... currently you are not making copies but copyA and copyB are just references pointing to geneA and geneB resp
Use Arrays.copy like so,
copyA = Arrays.copyOf(geneA, geneA.length);
copyB = Arrays.copyOf(geneB, geneB.length);
Upvotes: 2