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

    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 offline Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    14,423
    Blog Entries
    7
    Rep Power
    27

    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
    10

    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
    31

    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
    10

    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 offline Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    14,423
    Blog Entries
    7
    Rep Power
    27

    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
    31

    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
    10

    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, 05: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, 12:41 AM
  3. have an eventlistener change values
    By klmdb in forum New To Java
    Replies: 1
    Last Post: 03-20-2009, 12:42 AM
  4. Replies: 3
    Last Post: 01-26-2009, 12: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, 12: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
  •