def mutation(pop): """ Perform mutation on a population of individuals. Calls mutation operator as specified in params dictionary. :param pop: A population of individuals to be mutated. :return: A fully mutated population. """ # Initialise empty pop for mutated individuals. new_pop = [] # Iterate over entire population. for ind in pop: # Perform mutation. new_ind = params['MUTATION'](ind) # Check ind does not violate specified limits. check = check_ind(new_ind, "mutation") while check: # Perform mutation until the individual passess all tests. new_ind = params['MUTATION'](ind) # Check ind does not violate specified limits. check = check_ind(new_ind, "mutation") # Append mutated individual to population. new_pop.append(new_ind) return new_pop
def mutation(pop): """ Perform mutation on a population of individuals. Calls mutation operator as specified in params dictionary. :param pop: A population of individuals to be mutated. :return: A fully mutated population. """ # Initialise empty pop for mutated individuals. new_pop = [] # Iterate over entire population. for ind in pop: # If individual has no genome, default to subtree mutation. if not ind.genome and params['NO_MUTATION_INVALIDS']: new_ind = subtree(ind) else: # Perform mutation. new_ind = params['MUTATION'](ind) # Check ind does not violate specified limits. check = check_ind(new_ind, "mutation") breakout_count = 1 while check: if breakout_count > 500: new_ind = ind break # Perform mutation until the individual passes all tests. # If individual has no genome, default to subtree mutation. if not ind.genome and params['NO_MUTATION_INVALIDS']: new_ind = subtree(ind) else: # Perform mutation. new_ind = params['MUTATION'](ind) # Check ind does not violate specified limits. check = check_ind(new_ind, "mutation") breakout_count += 1 # Append mutated individual to population. new_pop.append(new_ind) return new_pop
def crossover_inds(parent_0, parent_1): """ Perform crossover on two selected individuals. :param parent_0: Parent 0 selected for crossover. :param parent_1: Parent 1 selected for crossover. :return: Two crossed-over individuals. """ # Create copies of the original parents. This is necessary as the # original parents remain in the parent population and changes will # affect the originals unless they are cloned. ind_0 = parent_0.deep_copy() ind_1 = parent_1.deep_copy() # Crossover cannot be performed on invalid individuals. if not params['INVALID_SELECTION'] and (ind_0.invalid or ind_1.invalid): s = "operators.crossover.crossover\nError: invalid individuals " \ "selected for crossover." raise Exception(s) # Perform crossover on ind_0 and ind_1. inds = params['CROSSOVER'](ind_0, ind_1) # Check each individual is ok (i.e. does not violate specified limits). checks = [check_ind(ind, "crossover") for ind in inds] if any(checks): # An individual violates a limit. return None else: # Crossover was successful, return crossed-over individuals. return inds
def mutation(pop): """ Perform mutation on a population of individuals. Calls mutation operator as specified in params dictionary. :param pop: A population of individuals to be mutated. :return: A fully mutated population. """ # Initialise empty pop for mutated individuals. new_pop = [] # Iterate over entire population. for ind in pop: # If individual has no genome, default to subtree mutation. if not ind.genome and params['NO_MUTATION_INVALIDS']: new_ind = subtree(ind) else: # Perform mutation. new_ind = params['MUTATION'](ind) # Check ind does not violate specified limits. check = check_ind(new_ind, "mutation") while check: # Perform mutation until the individual passes all tests. # If individual has no genome, default to subtree mutation. if not ind.genome and params['NO_MUTATION_INVALIDS']: new_ind = subtree(ind) else: # Perform mutation. new_ind = params['MUTATION'](ind) # Check ind does not violate specified limits. check = check_ind(new_ind, "mutation") # Append mutated individual to population. new_pop.append(new_ind) return new_pop