ec
Interface Prototype

All Known Subinterfaces:
Fitness, GPNodeParent, GPNodeSelector, Problem
All Known Implementing Classes:
BreedingSource, Individual, Species, ADFContext, GPNodeBuilder, GPData, GPFuncInfo, ADFStack

public interface Prototype
extends java.lang.Cloneable, Setup

Prototype classes typically have one or a few prototype instances created during the course of a run. These prototype instances each get setup(...) called on them. From then on, all new instances of a Prototype classes are Cloned from these prototype instances. This EC library uses Prototypes a lot. Individuals are prototypes. Species are prototypes. Fitness objects are prototypes. In the GP section, GPNodes and GPTrees are prototypes. The purpose of a prototype is to make it possible to ask classes, determined at run-time by user parameters, to instantiate themselves very many times without using the Reflection library, which would be very inefficient. Prototypes must be Cloneable, Serializable (through Setup), and of course, Setup.


Method Summary
 Parameter defaultBase()
          Returns the default base for this prototype.
 java.lang.Object protoClone()
          Creates a new individual cloned from a prototype, and suitable to begin use in its own evolutionary context.
 java.lang.Object protoCloneSimple()
          This should be implemented in a the top-level Prototype ONLY; in fact, it should probably be declared final.
 void setup(EvolutionState state, Parameter base)
          Sets up the object by reading it from the parameters stored in state, built off of the parameter base base.
 

Method Detail

protoClone

public java.lang.Object protoClone()
                            throws java.lang.CloneNotSupportedException
Creates a new individual cloned from a prototype, and suitable to begin use in its own evolutionary context.

The question here is whether or not this means to perform a "deep" or "light" ("shallow") clone, or something in-between. You may need to deep-clone parts of your object rather than simply copying their references, depending on the situation:

Implementations.

If you know that your superclasses will never change their protoClone() implementations, you might try inlining them in your overridden protoClone() method. But this is dangerous (though it yields a small net increase).

In general, you want to keep your deep cloning to an absolute minimum, so that you don't have to call protoClone() but one time.

The approach taken here is the fastest that I am aware of while still permitting objects to be specified at runtime from a parameter file. It would be faster to use the "new" operator; but that would require hard-coding that we can't do. Although using java.lang.Object.clone() entails an extra layer that deals with stripping away the "protected" keyword and also wrapping the exception handling (which is a BIG hit, about three times as slow as using "new"), it's still MUCH faster than using java.lang.Class.newInstance(), and also much faster than rolling our own Clone() method.


protoCloneSimple

public java.lang.Object protoCloneSimple()
This should be implemented in a the top-level Prototype ONLY; in fact, it should probably be declared final. It should be implemented as follows:

public final Object protoCloneSimple()
{
try { return protoClone(); }
catch (CloneNotSupportedException e) 
{ throw new InternalError(); } // never happens
} 

setup

public void setup(EvolutionState state,
                  Parameter base)
Sets up the object by reading it from the parameters stored in state, built off of the parameter base base. If an ancestor implements this method, be sure to call super.setup(state,base); before you do anything else.

For prototypes, setup(...) is typically called once for the prototype instance; cloned instances do not receive the setup(...) call. setup(...) may be called more than once; the only guarantee is that it will get called at least once on an instance or some "parent" object from which it was ultimately cloned.

Specified by:
setup in interface Setup

defaultBase

public Parameter defaultBase()
Returns the default base for this prototype. This should generally be implemented by building off of the static base() method on the DefaultsForm object for the prototype's package. This should be callable during setup(...).