def mut_shrink(individual: gp.PrimitiveTree, rng: random.Random) -> Tuple[gp.PrimitiveTree]: """Replace node with one of its arguments""" # We don't want to "shrink" the root if len(individual) < 3 or individual.height <= 1: return individual, iprims = [] for i, node in enumerate(individual[1:], 1): if isinstance(node, gp.Primitive) and node.ret in node.args: iprims.append((i, node)) if len(iprims) != 0: index, prim = rng.choice(iprims) arg_idx = rng.choice( [i for i, type_ in enumerate(prim.args) if type_ == prim.ret]) rindex = index + 1 for _ in range(arg_idx + 1): rslice = individual.searchSubtree(rindex) subtree = individual[rslice] rindex += len(subtree) slice_ = individual.searchSubtree(index) individual[slice_] = subtree return individual,
def cx_one_point( ind1: gp.PrimitiveTree, ind2: gp.PrimitiveTree, rng: random.Random) -> Tuple[gp.PrimitiveTree, gp.PrimitiveTree]: if len(ind1) < 2 or len(ind2) < 2: # No crossover on single node tree return ind1, ind2 # List all available primitive types in each individual types1 = collections.defaultdict(list) types2 = collections.defaultdict(list) for idx, node in enumerate(ind1[1:], 1): types1[node.ret].append(idx) for idx, node in enumerate(ind2[1:], 1): types2[node.ret].append(idx) common_types = set(types1.keys()).intersection(set(types2.keys())) if len(common_types) > 0: type_ = rng.choice(list(common_types)) index1 = rng.choice(types1[type_]) index2 = rng.choice(types2[type_]) slice1 = ind1.searchSubtree(index1) slice2 = ind2.searchSubtree(index2) ind1[slice1], ind2[slice2] = ind2[slice2], ind1[slice1] return ind1, ind2
def mut_uniform(individual: gp.PrimitiveTree, expr: Callable, pset: gp.PrimitiveSetTyped, rng: random.Random): """Replace subtree with randomly generated tree""" index = rng.randrange(len(individual)) slice_ = individual.searchSubtree(index) type_ = individual[index].ret individual[slice_] = expr(pset=pset, type_=type_) return individual,