I'm doing a lab at the moment working on fitness functions. The problem is I'm making a SmallChange() function that does what it says, annoyingly it seems to update the variable you give it, when it shouldn't.
Here's a copy of the full class: https://gist.github.com/1710367
Line 38 is the problem line.
And below is the function. When I give it solution
as an input it updates solution
with the small change it makes, but I can't figure out how or why.
Anyone know where I'm going wrong? It's starting to hurt my brain.
// Edits either the angle or velocity of our solution
// by a small amount (about 1% of the diffrence between max and min)
public static Double[] SmallChange(Double[] sol) {
// Pick a 0 or 1
switch (r.nextInt(2)) {
case 1: // Changing the angle
// The angle change amount
Double angle = (angleLimits[1] - angleLimits[0]) * 0.01;
// Make the change, either + or -
if (r.nextInt(2) == 0) {
sol[0] += angle;
} else {
sol[0] -= angle;
}
// Check it's within the limits
if (sol[0] > angleLimits[1]) {
sol[0] = angleLimits[1];
} else if (sol[0] < angleLimits[0]) {
sol[0] = angleLimits[1];
}
break;
case 0: // Changing the velocity
// The velocity change amount
Double velocity = (velocityLimits[1] - velocityLimits[0]) * 0.01;
// Make the change, either + or -
if (r.nextInt(2) == 0) {
sol[1] += velocity;
} else {
sol[1] -= velocity;
}
// Check it's within the limits
if (sol[1] > velocityLimits[1]) {
sol[1] = velocityLimits[1];
} else if (sol[1] < velocityLimits[0]) {
sol[1] = velocityLimits[1];
}
break;
}
return sol;
}
In Java, everything is passed by value - but that value is always either a primitive, or a reference.
So the value of any array variable is a reference to an array object. When you use that variable as an argument, the value (the reference) ends up as the initial value of the parameter. It's still referring to the same array object as the caller's variable - so any changes made to the array will be seen by the caller.
So just to clarify, your statement here is incorrect:
annoyingly it seems to update the variable you give it, when it shouldn't
It hasn't changed the value of the variable at all: that variable in the calling code still has the same value it did before, a reference to the same array. It's just that the method is changing the contents of the array.
It's like copying down your address on a piece of paper, then giving that to someone: they can't change where you live, but they can change the colour of your front door.
Now, to fix your problem...
If you want to clone the array, you'll have to do so explicitly. For example:
public static Double[] smallChange(Double[] sol) {
Double[] ret = (Double[]) sol.clone();
// Now work on ret instead of sol, and return ret at the end
You could reassign to sol
, but personally I wouldn't.
Note that you might also want to use a double[]
instead of Double[]
.