Source code for HyperGP.operators.mutation.tree_mut
from HyperGP.libs.states import VarStates, ProgBuildStates
from HyperGP.libs.utils import HalfAndHalf
from HyperGP.libs.regression.tree import TreeNode
import random
class MutMethod:
def __call__(self, *args, **kwargs):
raise NotImplementedError("No find '__call__' implement")
[docs]
class RandTrMut(MutMethod):
"""Perform the subtree mutation operation on the program.
Subtree mutation selects a random subtree from the embedded program to
be replaced. A donor subtree is generated at random and this is
inserted into the original parent to form an offspring. This
implementation uses the "headless chicken" method where the donor
subtree is grown using the initialization methods and a subtree of it
is selected to be donated to the parent.
"""
[docs]
def __call__(self, prog, cond: ProgBuildStates, prob=1, node_states=None, method=HalfAndHalf, **kwargs):
"""
Call RandTrMut method.
Args:
prog: The individual
cond: The 'cond' will be pass to the 'method' to generate the random subtree
prob: The probability to perform the subtree mutation.
method: The method called to generate subtree, in which the fixed parameter types:(cond, node_states) will be passed to in this call.
Returns:
A new prog
"""
if random.uniform(0, 1) < prob:
subtr_1 = prog.slice(random.randint(0, len(prog) - 1))
subtr_2 = method()(cond, node_states)
prog[subtr_1] = subtr_2
return prog
[docs]
class RandHoistMut(MutMethod):
"""Perform the hoist mutation operation on the program.
Hoist mutation selects a random subtree from the embedded program, replacing it by a random subtree of the selected mutation subtree.
"""
[docs]
def __call__(self, prog, prob=1):
"""
Call RandHoistMut method.
Args:
prog: The individual
prob: The probability to perform the subtree mutation.
Returns:
A new prog
"""
if random.uniform(0, 1) < prob:
rd_1 = random.randint(0, len(prog) - 1)
subtr_1 = prog.slice(rd_1)
subtr_2 = prog.slice(random.randint(rd_1, rd_1 + subtr_1 - 1))
prog[subtr_1] = prog[subtr_2]
return prog
[docs]
class RandPointMut(MutMethod):
"""Perform the point mutation operation on the program.
Point mutation selects a random node from the embedded program, replacing it by a random node from pset with the same arity.
"""
[docs]
def __call__(self, prog, cond: ProgBuildStates, prob=1):
"""
Call RandHoistMut method.
Args:
prog: The individual
cond: Used to generate new node to make point mutation. The `primitiveSet` module should be in it.
prob: The probability to perform the subtree mutation.
Returns:
A new prog
"""
if random.uniform(0, 1) < prob:
pset = cond.pset
rd_posi = random.randint(0, len(prog) - 1)
arity = prog.get_encode(rd_posi)[1]
if arity == 0:
prog[rd_posi] = cond.pset.selectTerminal()
else:
func_set = pset.primitiveSet
cdds = [func for func in func_set if pset.genFunc(func).arity == arity]
prog[rd_posi] = pset.genFunc(cdds[random.randint(0, len(cdds) - 1)])
return prog