def test_koza_maximization(): """ Tests the koza_parsimony() function for maximization problems """ problem = SpheroidProblem(maximize=True) pop = [] # We set up three individuals in ascending order of fitness of # [0, 1, 2] pop.append(Individual(np.array([0]), problem=problem)) pop.append(Individual(np.array([1]), problem=problem)) pop.append(Individual(np.array([0, 0, 1, 1]), problem=problem)) pop = Individual.evaluate_population(pop) # Now truncate down to the "best" that should be the third one best = ops.truncation_selection(pop, size=1) assert np.all(best[0].genome == [0, 0, 1, 1]) # This is just to look at the influence of the parsimony pressure on # the order of the individual. You should observe that the order is now # ([0,0,1,1], [0], [1]) because now their biased fitnesses are respectively # (-2, -1, 0) pop.sort(key=koza_parsimony(penalty=1)) # Ok, now we want to turn on parsimony pressure, which should knock the # really really really long genome out of the running for "best" best = ops.truncation_selection(pop, size=1, key=koza_parsimony(penalty=1)) assert np.all(best[0].genome == [1])
def test_truncation_parents_selection(): """ Test (mu + lambda), i.e., parents competing with offspring Create parent and offspring populations such that each has an "best" individual that will be selected by truncation selection. """ parents = [ Individual(np.array([0, 0, 0]), problem=MaxOnes()), Individual(np.array([1, 1, 0]), problem=MaxOnes()) ] parents = Individual.evaluate_population(parents) offspring = [ Individual(np.array([0, 0, 1]), problem=MaxOnes()), Individual(np.array([1, 1, 1]), problem=MaxOnes()) ] offspring = Individual.evaluate_population(offspring) truncated = ops.truncation_selection(offspring, 2, parents=parents) assert len(truncated) == 2 assert parents[1] in truncated assert offspring[1] in truncated
def test_truncation_selection_with_nan2(): """If truncation selection encounters a NaN and non-NaN fitness while minimizing, the non-NaN wins. """ problem = SpheroidProblem(maximize=False) pop = [] pop.append(Individual(np.array([0]), problem=problem)) pop.append(Individual(np.array([1]), problem=problem)) pop = Individual.evaluate_population(pop) # First *normal* selection should yield the 0 as the "best" best = ops.truncation_selection(pop, size=1) assert pop[0] == best[0] # But now let's set that best to a NaN, which *should* force the other # individual to be selected. pop[0].fitness = nan best = ops.truncation_selection(pop, size=1) assert pop[1] == best[0]
def test_truncation_selection(): """ Basic truncation selection test""" pop = [ Individual([0, 0, 0], decoder=IdentityDecoder(), problem=MaxOnes()), Individual([0, 0, 1], decoder=IdentityDecoder(), problem=MaxOnes()), Individual([1, 1, 0], decoder=IdentityDecoder(), problem=MaxOnes()), Individual([1, 1, 1], decoder=IdentityDecoder(), problem=MaxOnes()) ] # We first need to evaluate all the individuals so that truncation selection has fitnesses to compare pop = Individual.evaluate_population(pop) truncated = ops.truncation_selection(pop, 2) assert len(truncated) == 2 # Just to make sure, check that the two best individuals from the original population are in the selected population assert pop[2] in truncated assert pop[3] in truncated
def test_koza_minimization(): """ Tests the koza_parsimony() function for _minimization_ problems. """ problem = SpheroidProblem(maximize=False) pop = [] # First individual has a fitness of three but len(genome) of 4 pop.append(Individual(np.array([0, 1, 1, 1]), problem=problem)) # Second has a fitness of 4, but len(genome) of 1 pop.append(Individual(np.array([2]), problem=problem)) pop = Individual.evaluate_population(pop) best = ops.truncation_selection(pop, size=1, key=koza_parsimony(penalty=1)) assert np.all(best[0].genome == [2])
def test_lexical_minimization(): """ Tests lexical_parsimony() for minimization problems """ problem = SpheroidProblem(maximize=False) pop = [] # fitness=4, len(genome)=1 pop.append(Individual(np.array([2]), problem=problem)) # fitness=4, len(genome)=4 pop.append(Individual(np.array([1, 1, 1, 1]), problem=problem)) pop = Individual.evaluate_population(pop) best = ops.truncation_selection(pop, size=1, key=lexical_parsimony) # prefers the shorter of the genomes with equivalent fitness assert np.all(best[0].genome == [2])
def test_lexical_maximization(): """ Tests the lexical_parsimony() for maximization problems """ problem = MaxOnes() # fitness=3, len(genome)=6 pop = [Individual(np.array([0, 0, 0, 1, 1, 1]), problem=problem)] # fitness=2, len(genome)=2 pop.append(Individual(np.array([1, 1]), problem=problem)) # fitness=3, len(genome)=3 pop.append(Individual(np.array([1, 1, 1]), problem=problem)) pop = Individual.evaluate_population(pop) best = ops.truncation_selection(pop, size=1, key=lexical_parsimony) # prefers the shorter of the 3 genomes assert np.all(best[0].genome == [1, 1, 1])
def test_truncation_selection_with_nan1(): """If truncation selection encounters a NaN and non-NaN fitness while maximizing, the non-NaN wins. """ # Make a population where binary tournament_selection has an obvious # reproducible choice problem = MaxOnes() pop = [ Individual(np.array([0, 0, 0]), problem=problem), Individual(np.array([1, 1, 1]), problem=problem) ] # We first need to evaluate all the individuals so that truncation # selection has fitnesses to compare pop = Individual.evaluate_population(pop) # Now set the "best" to NaN pop[1].fitness = nan best = ops.truncation_selection(pop, size=1) assert pop[0] == best[0]
context['leap']['std'] = 2 # We use the provided context, but we could roll our own if we # wanted to keep separate contexts. E.g., island models may want to have # their own contexts. generation_counter = util.inc_generation(context=context, callbacks=(anneal_std, )) # print initial, random population print_population(parents, generation=0) while generation_counter.generation() < MAX_GENERATIONS: offspring = pipe( parents, ops.random_selection, ops.clone, mutate_gaussian(std=context['leap']['std']), ops.evaluate, ops.pool(size=len(parents) * BROOD_SIZE), # create the brood ops.truncation_selection(size=len(parents), parents=parents)) # mu + lambda parents = offspring generation_counter() # increment to the next generation # Just to demonstrate that we can also get the current generation from # the context print_population(parents, context['leap']['generation'])