def LTGE_crossover(p_0, p_1): """Crossover in the LTGE representation.""" # crossover and repair. # the LTGE crossover produces one child, and is symmetric (ie # xover(p0, p1) is not different from xover(p1, p0)), but since it's # stochastic we can just run it twice to get two individuals # expected to be different. g_0, ph_0 = latent_tree_repair( latent_tree_crossover(p_0.genome, p_1.genome), params['BNF_GRAMMAR'], params['MAX_TREE_DEPTH']) g_1, ph_1 = latent_tree_repair( latent_tree_crossover(p_0.genome, p_1.genome), params['BNF_GRAMMAR'], params['MAX_TREE_DEPTH']) # wrap up in Individuals and fix up various Individual attributes ind_0 = individual.Individual(g_0, None, False) ind_1 = individual.Individual(g_1, None, False) ind_0.phenotype = ph_0 ind_1.phenotype = ph_1 # number of nodes is the number of decisions in the genome ind_0.nodes = ind_0.used_codons = len(g_0) ind_1.nodes = ind_1.used_codons = len(g_1) # each key is the length of a path from root ind_0.depth = max(len(k) for k in g_0) ind_1.depth = max(len(k) for k in g_1) # in LTGE there are no invalid individuals ind_0.invalid = False ind_1.invalid = False return [ind_0, ind_1]
def LTGE_mutation(ind): """Mutation in the LTGE representation.""" # mutate and repair. g, ph = latent_tree_repair(latent_tree_mutate(ind.genome), params['BNF_GRAMMAR'], params['MAX_TREE_DEPTH']) # wrap up in an Individual and fix up various Individual attributes ind = individual.Individual(g, None, False) ind.phenotype = ph # number of nodes is the number of decisions in the genome ind.nodes = ind.used_codons = len(g) # each key is the length of a path from root ind.depth = max(len(k) for k in g) # in LTGE there are no invalid individuals ind.invalid = False return ind