On Nov 21, 2013, at 3:55 AM, Ralf Buschermöhle wrote:
> I need to distinguish GPNodes (of certain types) and references to these nodes.
> Afaik, "the implementation" (deep) clones (e.g., in the initial creation, mutation, crossover) everything, or am I missing something?
It sounds like what you want to do is have a GPNode A point to another GPNode B but not deep clone B when GPNode A is deep cloned. That's straightforward. Deep clone only clones stuff that ECJ knows about. It knows nothing of additional gunk you add to your GPNode subclass. So...
> 1.) Each GPNode need to get an ID (e.g., : Long) - something with a static Long to make sure that every instance ID is unique.
Instad of an ID, I'd just have a pointer directly to the underlying GPNode. Otherwise you have to store the GPNode in some hash table or array or whatnot and key it with that ID.
> 2.) A GPReference is an ERC (:Long).
An ERC yes, but I'd use a GPNode pointer rather than a long.
> 3.) A GPReference is bred after the "normal" breeding took place - because then the number of objects that can be referenced is available.
I think what you mean is that the reset() method needs to be delayed so it has something to reset to. I think that's reasonable.
What I would do is something like this:
1. reset() would set the pointer to null.
2. Create some method doReference() in GPIndividual which looks for GPReference nodes whose pointer is null and sets them to random GPNodes chosen from the population as you deem fit.
3. You'll need to call doReference() in your GPInitializer subclass like this:
public Population initialPopulation(EvolutionState state, int thread)
Population pop = super.initialPopulation(state, thread);
// now for each individual in pop, call doReference() on it
This will reset the references after population initialization.
4. Use your own subclass of GPBreedingPipeline and override this method:
public void finishProducing(EvolutionState state, int subpopulation, int thread)
super.finishProducing(state, subpopulation, thread);
// now for each individual in subpopulation, call doReference() on it
This will reset the references after breeding. It assumes that your references are only within a given subpopulation. Note that this method is only called in generational evolution; steady-state evolution (particularly asynchronous evolution) may never call it so you'll have to do something there, but you'll have bigger problems with those methods anyway. In that case, I'd just override produce() to reset the references.