# Values change when they're not supposed to

• 05-15-2010, 03:35 PM
m00nchile
Values change when they're not supposed to
One of my methods (actualy the workhorse method) from my genetic algorithm is doing something funky, and not in a good way. What I'm doing, is recording the best solution found and copying it directly into the new generation (elitism). But with a few System.out.println()'s I found that my best solution gets overwritten by a worse solution, even when my comparison returns false. Here's the code:
Code:

```//in SolutionSet class public void newGeneration() {                 Solution[] newGen = new Solution[solutions.length];                 if(bestSoFar == null) {                         Solution[] fittest2 = find2Fittest();                         newGen[0] = fittest2[0];                         newGen[1] = fittest2[1];                         bestSoFar = fittest2[0];                 }                 else {                         newGen[0] = bestSoFar; //first we add the best solution yet                         newGen[1] = findFittest(); //next we add the best of this generation                 }                 for(int i = 2; i < newGen.length; i+=2) {                         int parent1 = selectRoulette(); //selection of parents for crossover                         int parent2;                         int counter = 0;                         do {                                 counter++;                                 parent2 = selectRoulette();                                 if(counter > 15) {                                         parent2 = (parent1+1)%solutions.length;                                         break;                                 }                         } while(parent1 == parent2);                         Solution[] offspring = solutions[parent1].crossover(solutions[parent2]);                         newGen[i] = offspring[0];                         newGen[i].mutate();                         newGen[i].calcFitness();                         newGen[i+1] = offspring[1];                         newGen[i+1].mutate();                         newGen[i+1].calcFitness();                 }                 numGens++;                 solutions = newGen; //the new generation is set as the current                 Solution candidate = findFittest(); //get the best solution                 System.out.println(bestSoFar.getFitness()+" "+candidate.getFitness()+" "+(candidate.compareTo(bestSoFar) == -1)); //debugging                 if(candidate.compareTo(bestSoFar) == -1)                         bestSoFar = candidate;         }```
Now the compareTo of a solution is simple:
Code:

```//in Solution class public int compareTo(Solution s) { //smaller fitness score indicates better solution                 if(fitness < s.fitness) return -1;                 if(fitness > s.fitness) return 1;                 return 0;         }```
I'm really lost why this is happenning, even when the comparison in the if clause returns false, the value of bestSoFar changes, sample output:
Code:

```20.68888888888889 20.68888888888889 false //even though the comparison returns false 21.26086956521739 21.26086956521739 false //bestSoFar changes value```
• 05-15-2010, 03:44 PM
JosAH
I didn't read (and understand) all of your code (it's Saturday and I'm way too lazy today ;-) but I suspect that you're overwriting those array values in next iterations; when you find your best solution so far, make a copy of it and keep that instead of just the best solution so far.

kind regards,

Jos
• 05-15-2010, 03:46 PM
m00nchile
Yeah, I was suspecting referencing was the culprit.
• 05-15-2010, 03:47 PM
Fubarable
edit: never mind. Listen to Jos!
• 05-15-2010, 04:11 PM
m00nchile
Now I'm really getting wierded out, I've written up this method in my Solution class:
Code:

```public Solution copySolution() {                 Solution ret = new Solution(false);                 for(int i = 0; i < activeServers.length; i++) {                         ret.activeServers[i] = activeServers[i];                 }                 ret.fitness = fitness;                 ret.numServers = numServers;                 return ret;         }```
The activeServers variable is a boolean array, fitness is a double, numServers is an int. All are primitives (I'm copying the array one element at a time), and I've done a bit of testing to make sure they don't change behind your back because of referencing. When I set the value of bestSoFar in the newGeneration() method from the first post, I've substitued it with:
Code:

`bestSoFar = candidate.copySolution();`
Now, in my copySolution() method, I create a new instance of Solution, copy the array element by element do avoid referencing the same memory location, and copy the values of primitives only. I've even added a:
Code:

`System.out.println(bestSoFar == candidate);`
statement, that verifies that the 2 variables don't reference the same object. But the same thing is still happening, even after the deep cloning.
• 05-15-2010, 04:14 PM
JosAH
Quote:

Originally Posted by m00nchile
Now I'm really getting wierded out, I've written up this method in my Solution class:

Time to activate the poor man's debugger: System.out.println( ... ); print it the best solution so far at every step. The moment its value(s) change you found the bugger ...

kind regards,

Jos
• 05-15-2010, 04:14 PM
Fubarable
Are you setting bestSoFar anywhere else in your code?
• 05-15-2010, 04:16 PM
m00nchile
Heh, I did find the bugger. When copying the best solution to the next generation, I simply did:
Code:

`negGen[0] = bestSoFar;`
Adding in the cloning, it now works. Thanks for your help JosAH!