How to do a "cross-over" with two integer arrays - java

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!

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]

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);

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.

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);

Related

Splitting a 2D array into smaller equally sized 2D subarrays

Basically what I am asking is given a square 2D array and a valid patch size (the size of the 2D subarrays) how would I go about doing this.
Ultimately I don't need to store the subarrays in any way, I just need to find the median of each subarray and store them in a 1D array. The median and storing to new array are simple for me, I just can't figure out how to go about the original 2D array and splitting it properly.
I've attempted this several times and keep getting out of bounds errors.
I have a 4x4:
[1,2,3,4]
[2,3,4,1]
[3,4,1,2]
[4,1,2,3]
I need to split it like so
[1,2] [3,4]
[2,3] [4,1]
[3,4] [1,2]
[4,1] [2,3]
And then take the median of each and store them into a new 1D array.
EDIT: Solved, thanks for the help!
You can use Arrays.copyOfRange(Object[] src, int from, int to) for this where:
src is the source 1D array
from is the initial index of the range to be copied, inclusive.
to is the final index of the range to be copied, exclusive.
I don't prefer your code because it seems that it's time complexity is too high.
Try below code:
public class Temp {
public static void main(String[] args) {
int[][] arr = { { 1,2,3,4 },
{ 2,3,4,1 },
{ 3,4,1,2 },
{ 4,1,2,3 } };
int patch = 2;
splitToSubArrays(arr, patch);
}
static void splitToSubArrays(int arr[][], int patch) {
for (int i = 0; i < arr[0].length; i++) {
int to = patch;
for (int from = 0; to <= arr.length;) {
int a[] = Arrays.copyOfRange(arr[i], from, to);
// instead of printing you can store in a separate array for later usage
System.out.println(Arrays.toString(a));
to += patch;
from += patch;
}
}
}
}
EDIT: N.B.: For n*n array if n%patch is not 0 i.e. dimension is not divisible by patch value then you would need to use proper if condition here int a[] = Arrays.copyOfRange(arr[i], from, to); to control the index bound. Hope you are aware of this.
Output
[1, 2]
[3, 4]
[2, 3]
[4, 1]
[3, 4]
[1, 2]
[4, 1]
[2, 3]
I think something like this could do, altough i didn't test it, but It should give you a good idea of how to do this scan
public int[] patchArray(int[][] img, int patch)
{
int size = img.length * (img[0].length / patch) ;
int[] pArray = new int[size];
int[] tmp = new int[patch];
for (int row_i = 0; row_i < img.length; row_i++)
{
for (int patch_start = 0; patch_start < img[i].length; patch_start += patch)
{
int x = 0;
for (int patch_i = patch_start; patch_i < (patch_start + patch); patch_i++)
{
tmp[patch_i - patch_start] = img[row_i][patch_i];
}
calculateMedian(tmp);
}
}
return pArray;
}

Casting an Array of Integers into a Long

I am trying to typecast an integer array into a long array, but I don't quite know how to go about doing this.
So far, my code looks like this:
import java.util.Random;
public class main {
public static int[] sect(){
int[] returned = new int[4];
Random rand = new Random();
returned[0] = 4;
returned[1] = rand.nextInt(8) + 1;
returned[2] = rand.nextInt(7) + 1;
returned[3] = rand.nextInt(6) + 1;
return returned;
}
public static String num(){
for (int j = 0; j < 4; j++) {
int[] ints = sect();
for(int i =0; i < ints.length; i++) {
System.out.print(ints[i]);
}
}
return null;
}
}
I have tried doing things like:
return ((long)num());
But that never works. Does anyone know how I would go about doing this?
Are you using Java 8, if so this will work:
int[] arrayOfIntegers = {1, 2, 3, 4, 5, 6};
long[] arrayOfLongs = Arrays.stream(arrayOfIntegers).mapToLong(i -> i).toArray();
You can't do that.
You simply have to create an equal sized array, and copy the int values into that array. Unfortunately System.arraycopy() can not do that for you... So you can't avoid the manual copying here.
Because an array of int isn't an array of longs. Therefore there is no such cast as from a single int into a single long.

Why array is copied

I need help because I can not see where my problem is. I have function swapping and it looks like this:
public static void swapping(int[] curr, Integer i, Integer j, Integer k, Integer l, int z, int dist) {
int tmp;
int[] tmpCurr = curr;
if (i >= 0 && j >= 0 && k < 0 && l < 0) {
tmp = tmpCurr[i];
tmpCurr[i] = tmpCurr[z];
tmpCurr[z] = tmp;
nodesHM.put(1, tmpCurr);
for(int s = 0; s<tmpCurr.length; s++)
System.out.println(tmpCurr[s]);
tmpCurr = curr;
tmp = tmpCurr[j];
tmpCurr[j] = tmpCurr[z];
tmpCurr[z] = tmp;
nodesHM.put(2, tmpCurr);
for(int s = 0; s<tmpCurr.length; s++)
System.out.println(tmpCurr[s]);
}
}
i,j,k,l tell me what to swap with z. So if i put that somethig is -1 that means I do not want to swap it. Like it this case k and l.
And I call it from main, like this:
public static void main(String[] args) {
swapping(ourStartState, 3, 7, -1, -1, 6, 5);
}
private static final int[] ourStartState = { 1, 2, 3, 4, 5, 6, 0, 7, 8 };
And it should write me something like: 1,2,3,0,5,6,4,7,8 and 1,2,3,4,5,6,7,0,8
but it give me 1,2,3,0,5,6,4,7,8 and 1,2,3,0,5,6,7,4,8
Where I am going wrong?
Thanks
whenever you copy an array or an object, you just create another reference to the elements in the array.
so when you did tmpcurr=curr you created another reference to curr array, whatever changes you make in curr affects tmpcurr and vice-versa.
if you swap elements in tmpcurr array the elements of curr get swapped as well.
when you swapped elements again you are swapping from already swapped array.
this will help you How do I copy an object in Java?

Removing specific value from array (java)

i have integer a = 4 and array b 7,8,9,4,3,4,4,2,1
i have to write a method that removes int ALL a from array b
desired result 7,8,9,3,2,1
This is what I have so far,
public static int[] removeTwo (int x, int[] array3)
{
int counter = 0;
boolean[] barray = new boolean [array3.length];
for (int k=0; k<array3.length; k++)
{
barray[k] = (x == array3[k]);
counter++;
}
int[] array4 = new int [array3.length - counter];
int num = 0;
for (int j=0; j<array3.length; j++)
{
if(barray[j] == false)
{
array4[num] = array3[j];
num++;
}
}
return array4;
I get this error
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
at Utility.removeTwo(Utility.java:50)
at Utility.main(Utility.java:18)
Java Result: 1
Any help would be much appreciated!
The error stems from this for loop:
for (int k=0; k<array3.length; k++)
{
barray[k] = (x == array3[k]);
counter++;
}
when you create int[] array4 = new int [array3.length - counter]; you are creating an array with size 0. You should only increment the counter if the item is the desired item to remove:
for (int k=0; k<array3.length; k++)
{
boolean b = (x == array3[k]);
barray[k] = b;
if(b) {
counter++;
}
}
To answer your question in the comment, the method should be called and can be checked like this:
public static void main(String[] args) {
int[] array3 = {0,1,3,2,3,0,3,1};
int x = 3;
int[] result = removeTwo(x, array3);
for (int n : result) {
System.out.print(""+ n + " ");
}
}
On this line:
int[] array4 = new int [array3.length - counter];
You create an array with size 0, as counter is equal to array3.length at this point.
This means that you cannot access any index in that array.
You are creating
int[] array4 = new int [array3.length - counter];// 0 length array.
you can't have 0th index there. At least length should 1 to have 0th index.
BTW my suggestion, it is better to use List. Then you can do this easy.
Really an Array is the wrong tool for the job, since quite apart from anything else you will end up with stray values at the end that you cannot remove. Just use an ArrayList and that provides a removeAll() method to do what you need. If you really need arrays you can even do:
List<Integer> list = new ArrayList(Arrays.asList(array))
list.removeAll(4);
array = list.toArray();
(Exact method names/parameters may need tweaking as that is all from memory).
the simplest way is to work with a second array where you put in the correct values
something likte that
public static int[] removeTwo (int x, int[] array3)
{
int counter = 0;
int[] array4 = new int[array3.lenght];
for (int i = 0; i < array3.lenght; i ++) {
if(array3[i] == x){
array4[counter] = array3[i];
}
}
return array4;
}
anoterh way is to remove the x calue from the array3 and shift the values behind forward
The best way to remove element from array is to use List with Iterator. Try,
Integer[] array = {7, 8, 9, 4, 3, 4, 4, 2, 1};
List<Integer> list = new ArrayList(Arrays.asList(array));
for(Iterator<Integer> it=list.iterator();it.hasNext();){
if(it.next()==4){
it.remove();
}
}

Method in java to take array as parameter, copy first elements and then double the length?

I essentially want a method that takes in my declared array and then copies the elements into a new array and then doubles the size with the remaining elements as 0. How can I make this possible? I am confused on the doubling of the array, I realize I can equal the array to the previous array to copy the elements.
class Untitled
{
public static void main(String[] args)
{
int[] a = {6, 3, 5, 2};
}
public static int[] doubleSize(int[] j)
{
int[] new = int [] j + int[] j
return int[] j;
}
}
Java automatically initialized the elements in an integer array as 0, so you don't have to do that manually.
public static int[] doubleSize(int[] j)
{
int[] newArray = new int[j.length * 2]
for (int i = 0; i < j.length; i++) {
newArray[i] = j[i];
}
return newArray;
}
Edit: A more Java-esque solution is
public static int[] doubleSize(int[] j)
{
return Arrays.copyOf(j, 2 * j.length);
}
This is pretty simple. To create a new array with twice the length you can do:
int[] newArray = new int[j.length * 2];
Since the array is type int, each element will be initialized to 0.
So once you copy the elements from the old array you should be done.
Also, you will want to change your return statement to just
return newArray;
Hi you achieve required functionality in this way.
public class DoubleArray
{
public static void main( String[] args )
{
int a[]={2,3,4,5};
int b[]=new int[2*a.length];
b =Arrays.copyOf(a, b.length);
System.out.println("DoubleArray.main()"+b);
for(int i=0;i<b.length;i++)
{
System.out.println(b[i]);
}
}
}

Categories