Results 1 to 8 of 8
  1. #1
    m00nchile is offline Senior Member
    Join Date
    Feb 2010
    Location
    Ljubljana, Slovenia
    Posts
    470
    Rep Power
    5

    Default 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:
    Java 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:
    Java 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:
    Java Code:
    20.68888888888889 20.68888888888889 false //even though the comparison returns false
    21.26086956521739 21.26086956521739 false //bestSoFar changes value
    Ever seen a dog chase its tail? Now that's an infinite loop.

  2. #2
    JosAH's Avatar
    JosAH is online now Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,732
    Blog Entries
    7
    Rep Power
    21

    Default

    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

  3. #3
    m00nchile is offline Senior Member
    Join Date
    Feb 2010
    Location
    Ljubljana, Slovenia
    Posts
    470
    Rep Power
    5

    Default

    Yeah, I was suspecting referencing was the culprit.
    Ever seen a dog chase its tail? Now that's an infinite loop.

  4. #4
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,315
    Blog Entries
    1
    Rep Power
    26

    Default

    edit: never mind. Listen to Jos!

  5. #5
    m00nchile is offline Senior Member
    Join Date
    Feb 2010
    Location
    Ljubljana, Slovenia
    Posts
    470
    Rep Power
    5

    Default

    Now I'm really getting wierded out, I've written up this method in my Solution class:
    Java 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:
    Java 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:
    Java 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.
    Ever seen a dog chase its tail? Now that's an infinite loop.

  6. #6
    JosAH's Avatar
    JosAH is online now Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,732
    Blog Entries
    7
    Rep Power
    21

    Default

    Quote Originally Posted by m00nchile View Post
    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

  7. #7
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,315
    Blog Entries
    1
    Rep Power
    26

    Default

    Are you setting bestSoFar anywhere else in your code?

  8. #8
    m00nchile is offline Senior Member
    Join Date
    Feb 2010
    Location
    Ljubljana, Slovenia
    Posts
    470
    Rep Power
    5

    Default

    Heh, I did find the bugger. When copying the best solution to the next generation, I simply did:
    Java Code:
    negGen[0] = bestSoFar;
    Adding in the cloning, it now works. Thanks for your help JosAH!
    Ever seen a dog chase its tail? Now that's an infinite loop.

Similar Threads

  1. Replies: 1
    Last Post: 04-23-2010, 06:56 PM
  2. JButton doesn't disappear when it is supposed to?
    By ecliptical in forum New To Java
    Replies: 4
    Last Post: 01-25-2010, 01:41 AM
  3. have an eventlistener change values
    By klmdb in forum New To Java
    Replies: 1
    Last Post: 03-20-2009, 01:42 AM
  4. Replies: 3
    Last Post: 01-26-2009, 01:20 AM
  5. Help interpreting what a class is supposed to do
    By bornwithnoname in forum New To Java
    Replies: 2
    Last Post: 11-20-2008, 01:19 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •