-
Notifications
You must be signed in to change notification settings - Fork 77
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Elitism passes unfit candidates #34
Comments
Your understanding of how it should work is correct. It's fairly fundamental to how the evolution engine works so I'd be surprised if there was a bug that hadn't been spotted until now. Is your fitness evaluator repeatable (i.e. does it always return the same number for the same candidate)? Each candidate will be re-evaluated in each generation, even if they haven't changed. So if there's some random element to your fitness evaluation (e.g. if you're testing them against some randomly generated/sampled data) you could get a different score. |
I have experienced the same issue, and I use a deterministic fitness
evaluator (always the same fitness for the same candidate). Elitism is not
critical for me, so I've never delved into the code to see what was the
cause.
L.
…On Wed, 17 Apr 2019, 13:16 Dan Dyer, ***@***.***> wrote:
Your understanding of how it should work is correct. It's fairly
fundamental to how the evolution engine works so I'd be surprised if there
was a bug that hadn't been spotted until now. Is your fitness evaluator
repeatable (i.e. does it always return the same number for the same
candidate)? Each candidate will be re-evaluated in each generation, even if
they haven't changed. So if there's some random element to your fitness
evaluation (e.g. if your testing them against some randomly
generated/sampled data) you could get a different score.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#34 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ABGj5awb8vZHfBRd5d9PQO8kTg7MbUiZks5vhwKTgaJpZM4cxH1e>
.
|
Are you both using the GenerationalEvolutionEngine? If either of you can share any code that exhibits the problem I can take a look. |
I am using the GenerationalEvolutionEngine. I have noticed the elitism problem whether I use just mutation, or just crossover - I have included my implementations of those at the end, in case I am somehow operating on the previous generation's population, rather than mutating the new generation. Here is the evolveSchedule method I call in main, with no arguments:
If the problem were with my ScheduleEvaluator, then it would be in this class:
} I've elided the methods which read the excel files I'm using to build schedules(e.g., 'getMasterStudentList()'), because they're definitely always going to behave the same way each time they're called. What follows below are the 'mate' and 'mutate' methods inside the ScheduleMutator and ScheduleCrossover operators called by the evolutionary pipeline:
This is the mutate part:
I think that's all the pertinent code. |
I can't see anything obviously wrong there. One thing to be aware of is that the cross-over and mutation methods need to return objects that are entirely independent of the parents. Is there anything in your Schedule or Section classes that might be relevant there? For example, it looks like you're passing an array from one Schedule to the constructor of another. Does that mean that it's possible that two Schedules have references to the same mutable array object? Another thing to try would be to call setSingleThreaded on the evolution engine before calling evolve and see if you still see the same problem. It will be slower but will rule out any concurrency problems. |
It's as you say - there were constructors set up to generate 'references to the same mutable array object.' I changed my 'gets' to include a .clone(), and most of the issues went away. 10/10 on responses to a 10 year old project, Mr. Dyer! |
Glad you got it sorted. |
As I understand it, if elitism is a (legal) positive integer, then data.getBestCandidateFitness() should never decrease from generation to generation in my EvolutionObserver. I observe the best fitness fluctuating down as frequently as it goes up in my implementation. I'm pretty confident that my FitnessEvaluator is getting things right, consistently, as changing my evolution pipeline to include only the IdentityOperator returns the same value from generation to generation, meaning at least that the 'best' candidate is getting the same fitness evaluation.
Is there anything I could have written (candidate factory, evolution operators) besides the Fitness Evaluator that could cause data.getBestCandidateFitness() to decrease?
Or, is elitism (or my understanding of what it does) broken?
The text was updated successfully, but these errors were encountered: