|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: INNER | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object | +--ec.gp.GPType
GPType is a Clique which represents types in Strongly-Typed Genetic Programming (STGP). (David Montana, "Strongly-Typed Genetic Programming", Evolutionary Computation 3(2), pp. 199-230).
In STGP, each function node has a return-type, and each of its arguments also have assigned types. Furthermore, the tree itself has a predefined "tree type". STGP permits crossover and mutation of trees only with the constraint that each node's return type "fits" with the corresponding argument type in the node's parent; further, the root node's return type must "fit" with the tree type.
The simplest definition of "fit" is that the types must be the same. Montana calls this "Basic" STGP (see section 2.1). This is the form of STGP that most implementations do, and it's not very powerful.
This GP implementation handles most of the more powerful notion of generic functions and generic types, discussed in Montana section 2.2 and 2.3. The way this is done is by differentiating between two kinds of type classes: atomic types, and set types.
An atomic type is a basic GP type. Atomic types "fit" only if they're the same object (this implementation uses == ). A problem domain that only uses atomic types is essentially doing "Basic" STGP.
Set types are sets of atomic types. A set type "fits" with an atomic type only if it contains the atomic type in its set. A set type "fits" with another set type only if they share at least one atomic type in common (that is, the intersection of their sets is nonempty).
Set types allow for types which can fit in several different generic places -- an object can now say that it "fits" with types A or B or C, but not D or E.
GPTypes are a Clique, and they set themselves up as a group; in general you should not create any new GPTypes. You should also not attempt to clone them, since type equivalence is determined partially by pointer equivalence.
What Set and Atomic Types Can Do. This construction is pretty powerful, and most interesting variations on Strongly-Typed programming of late can be done nicely with set and atomic types and a little cleverness. For example, I am fairly certain that atomic types and set types can be used to implement any mechanism devisable using type inheritance along the lines of (Thomas Haynes, Dale Schoenefeld, and Roger Wainwright, "Type Inheritance in Strongly Typed Genetic Programming", Advances in Genetic Progrmming 2, pp. 359-376. Let's say that you wanted to define some classes a-la Haynes et al with multiple inheritance, say, a Vehicle, a Red-Thing, a Car (which is a Vehicle), a Truck (which is a Vehicle), and a Fire-Truck (which is a Truck and a Red-Thing). Now, you want to guarantee that children nodes fit with parents only if the return value of the children node is a subclass of the parents' argument slot. You can do this as follows: first, you create an atomic type for each of the classes above. Then you create the set types: Vehicle-S = {Vehicle}, Red-Thing-S = {Red-Thing}, Car-S = {Car,Vehicle}, Truck-S = {Truck,Vehicle}, and Fire-Truck-S = {Fire-Truck,Truck,Red-Thing}. Then you set up your function sets so that the return type of each node is an atomic type, and the argument types of nodes are set types. For example, if the function FOO is supposed to take a Fire Truck and a Car and return another Car, then you set the return type to Car, the first argument type to Fire-Truck-S, and the second return type to Car-S. The rest is left up to the reader as an excercise :-)
I also believe that set types and atomic types can handle most grammar-based mechanisms I've seen, which in general appear reducable to STGP anyway; for example, in Eric Jones and William Joines, "Genetic Design of Electronic Circuits". Late-Breaking Papers at the 1999 Genetic and Evolutionary Computatiokn Conference. 124-133.
One interesting mention is Montana's depiction of "Generic Functions". As Montana describes it, a Generic Function takes generic argument types and returns a generic return type of some sort. Although he states that such a function should have a return type that is "well defined" for each set of generic argument types, his examples do not bear this out. Nonetheless, it is an interesting issue as to how to handle true Generic Functions with well-defined types.
I define a Generic Function as a relation mapping a particular return type for a function with some permutation of argument types provided. That is, the return type is a function T(a1,a2,a3...), where a1,... are the return types of the particular children plugged into argument slots the function. One issue that must be dealt with is the direction of flow in this typing: does the return type of the function dictate the permutation of argument types, or is it the other way around? This becomes important during crossover for example -- a subtree swapped into a new parent may be valid with that parent only if the subtree root's children types can be modified -- this may then touch off a flow throughout the subtree to see if all the children nodes can transitively adjust themselves such that the subtree is valid. Or, if the argument types dictate the return type, then perhaps the new subtree's plugging-into its parent might touch off an upward flow of return type changes. At any rate, this area hasn't been well studied.
Anyhow, if one assumes that Generic Functions are fixed in their types once they become "instantiated" in some tree, that is, they're kind of like Ephemeral Random Constants, then you can implement Generic Functions trivially by simply implementing each possible relational mapping as a seperate function node. You might want to decrease the possible number of these nodes' appearance relative to other nodes in order to make them have roughly the same probability of appearance as a single Generic Function: PTC1 and PTC2 provide this.
Parameters
base.a.size int >= 1 |
(number of atomic types) |
base.s.size int >= 0 |
(number of set types) |
Field Summary | |
static java.util.Hashtable |
all
A global storage facility for all known GPTypes. |
java.lang.String |
name
The name of the type |
static int |
numAtomicTypes
The number of atomic types |
static int |
numSetTypes
The number of set types |
static java.lang.String |
P_ATOMIC
|
static java.lang.String |
P_NAME
|
static java.lang.String |
P_SET
|
static java.lang.String |
P_SIZE
|
int |
type
The preassigned integer value for the type |
Constructor Summary | |
GPType()
|
Method Summary | |
abstract boolean |
compatibleWith(GPType t)
Am I compatible with ("fit" with) t? For two atomic types, this is done by direct pointer equality. |
static void |
postProcessTypes()
Assigns unique integers to each atomic type, and sets up compatibility arrays for set types. |
void |
readObject(java.io.ObjectInputStream in)
|
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. |
static void |
setupTypes(EvolutionState state,
Parameter base)
Sets up all the types, loading them from the parameter file. |
java.lang.String |
toString()
Returns the type's name |
static GPType |
typeFor(java.lang.String name,
EvolutionState state)
Returns a type for a given name. |
void |
writeObject(java.io.ObjectOutputStream out)
|
Methods inherited from class java.lang.Object |
clone,
equals,
finalize,
getClass,
hashCode,
notify,
notifyAll,
wait,
wait,
wait |
Field Detail |
public static final java.lang.String P_NAME
public static final java.lang.String P_ATOMIC
public static final java.lang.String P_SET
public static final java.lang.String P_SIZE
public java.lang.String name
public int type
public static java.util.Hashtable all
public static int numAtomicTypes
public static int numSetTypes
Constructor Detail |
public GPType()
Method Detail |
public abstract boolean compatibleWith(GPType t)
public java.lang.String toString()
public static void setupTypes(EvolutionState state, Parameter base)
public static void postProcessTypes()
public void setup(EvolutionState state, Parameter base)
public static GPType typeFor(java.lang.String name, EvolutionState state)
public final void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException
public final void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException
|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: INNER | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |