Print

Print


Hi Sean - thanks a bunch for the reply, I'll be looking into this further asap!

Cheers!

Sent from NSA HQ
  Original Message  
From: Sean Luke
Sent: Woensdag 25 Junie 2014 05:02
To: [log in to unmask]
Reply To: ECJ Evolutionary Computation Toolkit
Subject: Re: Serializing a GP Individual for later use ("execution"), using ECJ 21

On Jun 24, 2014, at 3:40 PM, Hendrik Coetzee <[log in to unmask]> wrote:

> I'm hoping somebody can point me in the right direction with this.
> Essentially I'm trying to:
> 1) evolve a suitable GP individual (well on my way with this)
> 2) Serializes/store the resulting tree (seem to be able to do this)
> 3) De-serialize/load the individual at a later stage (can do it sorta?)
> 4) Feed it parameters, and run it to get a result. (um?)
> 
> I have posted this question (with code sample) on StackOverflow:http://stackoverflow.com/questions/24373981/serializing-ecj-gp-individual-for-later-execution
> 
> It looks like I'm almost there - but I'm hitting a speed bump with the following:
> a) executing/evaluating/running a GP individual outside of the GP evolutionary stack seems problematic (lots of scaffolding required)
> b) Code sample as provided currently requires the original Species object in order to instantiate a new Individual based on the serialized output. This is sorta sucky, since at the point I will need to get things thing running again, that object will be long gone.

I don't think that a GPIndividual needs its fitness nor species to be run properly. So just do serialization like this:

Species s = individual.species;
Fitness f = individual.fitness;
individual.species = null;
individual.fitness = null;
// serialize out the individual here
individual.species = s;
individual.fitness = f;

After you have deserialized the individual, the only other thing you'll need is your own executor separate from individual.evaluate(). Typically the only thing that an individual needs out of the EvolutionState passed in is its random number generators. If your individual needs that, then you can just do:

long seed = ...
EvolutionState state = new EvolutionState();
state.random = new MersenneTwisterFast[1];
state.random[0] = new MersenneTwisterFast(seed);

Now you make a version of evaluate which doesn't assess fitness, and add it as a method to your GPProblem. For example, you could do this for Artificial Ant (in Ant.java):

public void evaluate2(EvolutionState state, // pass in your fake state here
final Individual ind)
{
int threadnum = 0; // we assume we're single threaded here

sum = 0; 
posx = 0;
posy = 0;
orientation = O_RIGHT;

for(moves=0;moves<maxMoves && sum<food; )
((GPIndividual)ind).trees[0].child.eval(
state,threadnum,input,stack,((GPIndividual)ind),this);

// clean up array
for(int y=0;y<food;y++)
map[foodx[y]][foody[y]] = FOOD;
}

Now all that's left is instantiating your GPProblem subclass. GPProblem has a few special objects that need to be built (the ADFStack and the GPData), but they're pretty easy. Let's say your GPProblem subclass is is a MyProblem and your GPData subclass is a MyData.

ec.gp.ADFStack stack = new ec.gp.ADFStack();
stack.context_proto = new ec.gp.ADFContext();
MyProblem problem = new MyProblem();
problem.stack = stack;
problem.input = new MyData();

Now you should be ready to go:

problem.evaluate2(state, deserializedIndividual);

Sean