Hmmm...
Further to the type question, I got my answer but am having a few other
issues. The trees seem to build ok with the types in place but I get warnings
and crashes on larger populations. What can I do to fix these? I'd rather do the
typing upfront, and with small populations it works great.
Should I just define the tS, cS, and oS types for the root as well? Is this part a
major issue? In a previous try I over-rode all instances of nil for
NodeConstraints.
WARNING:
In function set f0 for the GPTreeConstraints tc0, no *nonterminals* are given
with the return type tS which is required by other functions in the function set
or by the tree's return type. This may or may not be a problem for you.
PARAMETER: gp.tc.0
WARNING:
In function set f0 for the GPTreeConstraints tc0, no *nonterminals* are given
with the return type oS which is required by other functions in the function set
or by the tree's return type. This may or may not be a problem for you.
PARAMETER: gp.tc.0
WARNING:
In function set f0 for the GPTreeConstraints tc0, no *nonterminals* are given
with the return type cS which is required by other functions in the function set
or by the tree's return type. This may or may not be a problem for you.
PARAMETER: gp.tc.0
WARNING:
In function set f0 for the GPTreeConstraints tc0, no terminals are given with
the return type root which is required by other functions in the function set or
by the tree's return type. Nearly all tree-builders in ECJ require the ability to
add a terminal of any type for which there is a nonterminal, and at any time.
Without terminals, your code may not work. One common indication that a
tree-builder has failed due to this problem is if you get the MersenneTwister
error 'n must be positive'.
PARAMETER: gp.tc.0
WARNING:
In function set f0 for the GPTreeConstraints tc0, no terminals are given with
the return type nil which is required by other functions in the function set or by
the tree's return type. Nearly all tree-builders in ECJ require the ability to add
a terminal of any type for which there is a nonterminal, and at any time.
Without terminals, your code may not work. One common indication that a
tree-builder has failed due to this problem is if you get the MersenneTwister
error 'n must be positive'.
PARAMETER: gp.tc.0
and...
Initializing Generation 0
ONCE-ONLY WARNING:
A GPNodeBuilder has been requested at least once to generate a one-node tree
with a return value type-compatable with a certain type; but there is no
TERMINAL which is type-compatable in this way. As a result, the algorithm
was forced to use a NON-TERMINAL, making the tree larger than requested,
and exposing more child slots to fill, which if not carefully considered, could
recursively repeat this problem and eventually fill all memory.
ONCE-ONLY WARNING:
class ec.gp.koza.HalfBuilder can't find a terminal type-compatable with nil
ONCE-ONLY WARNING:
A GPNodeBuilder has been requested at least once to generate a tree with a
return value type-compatable with a certain type; but there is no NON-
TERMINAL which is type-compatable in this way. As a result, the algorithm
was forced to use a TERMINAL, making the tree smaller than requested.
ONCE-ONLY WARNING:
class ec.gp.koza.HalfBuilder can't find a non-terminal type-compatable with tS
ONCE-ONLY WARNING:
class ec.gp.koza.HalfBuilder can't find a non-terminal type-compatable with cS
ONCE-ONLY WARNING:
class ec.gp.koza.HalfBuilder can't find a non-terminal type-compatable with oS
And, indeed I crapped out memory with a 3000 population...
Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit
exceeded at java.util.Arrays.copyOf(Arrays.java:2367)...
I noticed this warning in the noerc2.params file...
# The gotcha: many GP node builders require that for every
# reachable type used by nodes in the function set there
# must exist at least one terminal (and ideally one nonterminal)
# in the function set which returns that type. This is
# because many GP node builder algorithms insist on being
# able to emit a terminal whenever they so desire, regardless
# of what the current type situation is where the terminal
# has to be hung. The notable exception to this is Uniform.
# Ordinarily this would be a problem for us as we use
# Ramped Half-and-Half as our builder, and it has this
# requirement. However since we are telling Ramped Half-and-Half
# to generate only trees of sizes 2 and up (NOT 1 and up),
# it will never attempt to select a terminal for the root
# and this gotcha will not occur. The issue would also come
# up if we use tree mutation as an operator rather than solely
# crossover. But we're not doing that.
Here's my relevant setup...
# use one function set
gp.fs.size = 1
gp.fs.0 = ec.gp.GPFunctionSet
# call it "f0".
gp.fs.0.name = f0
# 2 functions and 3 ERC terminals in the simple function set
gp.fs.0.size = 5
gp.fs.0.func.0 = ec.csc495.gp.test.timeslot.Join
gp.fs.0.func.0.nc = nc2
gp.fs.0.func.1 = ec.csc495.gp.test.timeslot.JoinERC
gp.fs.0.func.1.nc = nc3
gp.fs.0.func.2 = ec.csc495.gp.test.timeslot.TsERC
gp.fs.0.func.2.nc = nc0
gp.fs.0.func.3 = ec.csc495.gp.test.timeslot.CsERC
gp.fs.0.func.3.nc = nc0
gp.fs.0.func.4 = ec.csc495.gp.test.timeslot.OsERC
gp.fs.0.func.4.nc = nc0
# set up types
gp.type.a.size = 5
gp.type.a.0.name = nil
gp.type.a.1.name = root
gp.type.a.2.name = cS
gp.type.a.3.name = oS
gp.type.a.4.name = tS
gp.type.s.size = 1
gp.type.s.0.name = nil-and-root
gp.type.s.0.size = 2
gp.type.s.0.member.0 = nil
gp.type.s.0.member.1 = root
# make new constraints forms
gp.nc.size = 12
gp.nc.7 = ec.gp.GPNodeConstraints
gp.nc.7.name = nc-returning-nil-and-root
gp.nc.7.returns = nil-and-root
gp.nc.7.size = 2
gp.nc.7.child.0 = nil
gp.nc.7.child.1 = nil
gp.nc.8 = ec.gp.GPNodeConstraints
gp.nc.8.name = nc-accepting-erc
gp.nc.8.returns = nil
gp.nc.8.size = 3
gp.nc.8.child.0 = tS
gp.nc.8.child.1 = cS
gp.nc.8.child.2 = oS
gp.nc.9 = ec.gp.GPNodeConstraints
gp.nc.9.name = nc-returns-tS
gp.nc.9.returns = tS
gp.nc.9.size = 0
gp.nc.10 = ec.gp.GPNodeConstraints
gp.nc.10.name = nc-returns-cS
gp.nc.10.returns = cS
gp.nc.10.size = 0
gp.nc.11 = ec.gp.GPNodeConstraints
gp.nc.11.name = nc-returns-oS
gp.nc.11.returns = oS
gp.nc.11.size = 0
# keep it this way so that this code may be easily commented out
# redefine Join, JoinERC, TsERC, CsERC, OsERC
gp.fs.0.func.0.nc = nc-returning-nil-and-root
gp.fs.0.func.1.nc = nc-accepting-erc
gp.fs.0.func.2.nc = nc-returning-tS
gp.fs.0.func.3.nc = nc-returning-cS
gp.fs.0.func.4.nc = nc-returning-oS
# define the tree so that it only accepts items that are compatible with
# root -- Join is the only such item
gp.tc.0.returns = root
-- ray
|