def test_grow_tree2(): np.random.seed(45345) pset = pg.PrimitiveSet() pset.addFunction(op.add, 2) pset.addFunction(op.sub, 2) pset.addTerminal(1) pset.addTerminal(2) pset.addTerminal(3) pset.addVariable("x") init_max_depth = 3 max_depth = 6 tree = pg.grow_tree(pset, init_max_depth, max_depth) assert np.array_equal(tree, np.array([1, 4, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]))
def test_grow_tree1(): np.random.seed(45345) pset = pg.PrimitiveSet(typed=True) pset.addFunction(op.add, 2, [int, int, int]) pset.addFunction(op.sub, 2, [int, int, int]) pset.addTerminal(1, [int]) pset.addTerminal(2, [int]) pset.addTerminal(3, [int]) pset.addVariable("x", [int]) init_max_depth = 3 max_depth = 6 tree = pg.grow_tree(pset, init_max_depth, max_depth) assert np.array_equal(tree, np.array([1, 4, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]))
def test_grow_tree_ephemeral_typed1(): np.random.seed(45345) pset = pg.PrimitiveSet(typed=True) pset.addFunction(op.add, 2, [float, float, float]) pset.addFunction(op.sub, 2, [float, float, float]) pset.addTerminal(float_constants, types=[float], ephemeral=True) init_max_depth = 5 max_depth = 6 tree = pg.grow_tree(pset, init_max_depth, max_depth) tree_str = pg.interpreter(pset, tree) assert np.array_equal(tree, np.array([ 1, 4, 2, 2, 1, 5, 6, 2, 7, 8, 1, 1, 9, 10, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])) assert tree_str == 'add(0.6948470578046806, sub(sub(add(0.23851088045334068, 0.7485138905722925), sub(0.9421360052961212, 0.5983584346144624)), add(add(0.6952518271609337, 0.41227782045980343), 0.13638623666489624)))' assert pset.num_primitives == 11 assert pset.ephemeral_cache == {3} assert pset.ephemeral_constants == {4: (0.6948470578046806, [float]), 5: (0.23851088045334068, [float]), 6: (0.7485138905722925, [float]), 7: (0.9421360052961212, [float]), 8: (0.5983584346144624, [float]), 9: (0.6952518271609337, [float]), 10: (0.41227782045980343, [float]), 11: (0.13638623666489624, [float])}
def test_grow_tree3(): np.random.seed(12345) pset = pg.PrimitiveSet(typed=True) pset.addFunction(op.add, 2, [int, int, int]) pset.addFunction(op.sub, 2, [float, int, int]) pset.addFunction(op.mul, 2, [int, float, float]) pset.addFunction(op.truediv, 2, [float, float, float]) pset.addTerminal(1, [int]) pset.addTerminal(2, [int]) pset.addTerminal(3, [int]) pset.addTerminal(4.0, [float]) pset.addTerminal(5.0, [float]) pset.addTerminal(6.0, [float]) pset.addVariable("x", [float]) pset.addVariable("y", [int]) init_max_depth = 2 max_depth = 2 tree = pg.grow_tree(pset, init_max_depth, max_depth) assert np.array_equal(tree, np.array([3, 9, 9, 0]))
def subtree_mutation(parent, pset=None, **kargs): ''' SubTree Mutation Args: parent (TreeIndividual): the individual to be mutated pset (PrimitiveSet): the set primitives allowed to be used Returns: mutated individual ''' def arraycopy(src, src_pos, dest, dest_pos, length): dest[dest_pos:dest_pos + length] = src[src_pos:src_pos + length] def get_primitive_type(primitive): if primitive in pset.ephemeral_constants: _, p_type = pset.ephemeral_constants[primitive] elif primitive in pset.terminals: _, p_type = pset.terminals[primitive] elif primitive in pset.variables: _, p_type = pset.variables[primitive] elif primitive in pset.functions: _, _, p_type = pset.functions[primitive] else: p_type = None raise AttributeError( 'This is a typed primitive set so types are required!') return p_type[0] offspring = pg.TreeIndividual( tree=np.zeros(parent.genotype.size, dtype=parent.genotype.dtype)) # define tree cut points for subtree replacement start1 = np.random.randint(parent.nodes) end1 = pg.transverse_tree(pset, parent.genotype, start1) # if typed subtree must return the appropriate type if pset.typed: primitive = parent.genotype[start1] parent_type = get_primitive_type(primitive) else: parent_type = None # TODO: the default values to set the size of the generated tree must be revised # and a proper mechanism to set these values on a per-problem case must be available # if typed set, start2 must be of the same type as start1 try: subtree = pg.grow_tree(pset, parent.depth - 1, parent.depth, initial_type=parent_type) except: e = sys.exc_info()[0] print('%s' % e) print('parent.depth: %s' % parent.depth) start2 = 0 end2 = pg.transverse_tree(pset, subtree, start2) len1 = start1 + (end2 - start2) + (parent.nodes - end1) # produce offpsring 1 arraycopy(parent.genotype, 0, offspring.genotype, 0, start1) num_elements = (end2 - start2) arraycopy(subtree, start2, offspring.genotype, start1, num_elements) num_elements = (parent.nodes - end1) arraycopy(parent.genotype, end1, offspring.genotype, start1 + (end2 - start2), num_elements) # update tree metrics offspring.depth, offspring.nodes = pg.count_tree_internals( pset, offspring.genotype) if offspring.nodes <= parent.genotype.size: return offspring else: return parent