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
|