On Jul 27, 2005, at 12:00 AM, Mozaherul Hoque Abul Hasanat wrote: Is there any way to specify the root nodes of the GP individuals to be a particular function, say .. Division or Multiplication? Absolutely. Here's an example params file. ###### example params file, goes in ec/app/regression parent.0 = ./noerc.params # To require that the root of a tree be a given node, you # simply need to set up the typing so that that node is # the only node which is compatable with the tree's return # type. The way to do this is to make not one but two # atomic types (in the example below, nil and root). nil # is the default type used by our GP nodes. root will be # the return type of the tree. Then we create a set-type # which is compatable with both of them called nil-and-root, # and set things up so the return type of our desired node # (in this case, 'div'), returns nil-and-root. Thus 'div' # is legal to hang as root (and is the only such node), AND # 'div' is still perfectly compatible as a child of other # nodes as before (because it still meshes with nil). # 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. # We have only one node which returns nil-and-root, # and it's a nonterminal ('div'). Is this going to trip us up? # No. Ordinarily it 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. # If you want to see the problem occur, change Ramped Half-and-Half # to generate trees of sizes 1 and up. Then occasionally it'll try # to make a tree that's just a terminal which returns root-and-nil, # and there is no node that can fill that requirement. Here's the # parameter which will make that happen: # gp.koza.half.min-depth = 1 # Okay, here we go. # Add an atomic type (root) and a set type # (nil-and-root) which is compatible with both # nil and root gp.type.a.size = 2 gp.type.a.0.name = nil gp.type.a.1.name = root 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 a new contraints form for div which returns # things of type nil-and-root. This is compatable # with all elements that accept nil (which will be # all other functions), so div will still fit right in. # Note that this constraints takes two kids just like # div would expect. gp.nc.size = 8 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 # redefine div to return things of type nil-and-root. # (in erc.params, div is function 4) gp.fs.0.func.4.nc = nc-returning-nil-and-root # define the tree so that it only accepts items that # are compatible with root. div will be the only # such item. gp.tc.0.returns = root ###### end example