Print

Print


Robert Baruch wrote:

> Thanks for the advice and the explanation. In looking through the code, 
> my first idea had been to extend MasterProblem and use that as 
> eval.masterproblem, but my teeth did some grinding when I found out that 
> the master code requires eval.masterproblem to be exactly equal to 
> MasterProblem.  I could not augment the standard evil overlord with more 
> evil overlordness of my own. (Shouldn't MasterProblem be a final class, 
> then?)

I'm pretty sure that's not true.  You can subclass MasterProblem to your 
heart's content:

public class Foo extends ec.eval.MasterProblem { }

	eval.masterproblem = Foo

Double-checking this *did* cause me to run across a bug in ECJ, but it 
doesn't affect you.  Specifically, ECJ's even looser: it lets ANY 
subclass of Problem be loaded as a MasterProblem, which causes ECJ to 
bomb later.  I've cleaned that up -- now it has to be a MasterProblem or 
a subclass thereof.

It *is* true that SlaveMonitor, SlaveConnection, and Job are among the 
very few hard-coded classes in ECJ: that code is too interwoven for us 
to want people to swap in other classes (for now).  Plus, it works as a 
black box anyway.  But MasterProblem, sure, go to town.


> So my next idea had been to hack MasterProblem as you suggested, but I 
> really hated doing that, because then when the next ECJ version came out 
> (and they've been coming out relatively fast and furious), I'd have to 
> remember the changes I made. I could always stick with the current ECJ 
> version, but I'm one of those upgrade addicts.
 >
> Finally, I settled on creating a custom Exchanger, that being the next 
> stage after evaluation, and fix up the fitnesses in the prebreeding 
> exchange phase. Not ideal, but it's the very next phase after 
> evaluation, and at least it would work for future ECJ versions.

Usually your best bet for forward-compatable hooks is Statistics.


> IMHO, the best thing would be to fix up MasterProblem, but I also didn't 
> look at it closely enough to determine whether that would work under 
> both synchronous and asynchronous evaluation. I defer to your far 
> greater knowledge of the code :)

Well, in asynchronous evaluation, finishEvaluating is NEVER CALLED.  So
that wouldn't be great for you.  But on the other hand, it's 
asynchronous, which is to say, steady-state, so there's no real 
generational boundary being checked in the Problem.

Sean