Program Teams¶
Packed fitness_case_matrix and sel_team on a small case set where
no single 3-bit genome can cover every case. See the
columnar programs tutorial.
import numpy
from deap_er import Fitness, Toolbox, creator, tools
tools.rng.seed(1234) # disables randomization
# Four cases; a 3-bit genome can solve at most three of them.
N_CASES = 6
IND_SIZE = 3
# Case i is solved when gene i % 3 equals TARGET[i].
TARGET = (1, 0, 1, 0, 1, 0)
def evaluate(individual):
return tuple(0.0 if individual[i % IND_SIZE] == TARGET[i] else 1.0 for i in range(N_CASES))
def solved_count(values):
return sum(abs(error) < 1e-12 for error in values)
def setup():
creator.create_type("FitnessMin", Fitness, weights=(-1.0,) * N_CASES)
creator.create_type("Individual", list, fitness=creator.FitnessMin)
toolbox = Toolbox()
toolbox.register("attr_bool", tools.rng.randint, 0, 1)
toolbox.register(
"individual",
tools.init_repeat,
creator.Individual,
toolbox.attr_bool,
IND_SIZE,
)
toolbox.register("population", tools.init_repeat, list, toolbox.individual)
toolbox.register("mate", tools.cx_two_point)
toolbox.register("mutate", tools.mut_flip_bit, mut_prob=0.3)
toolbox.register("select", tools.sel_tournament, contestants=3)
toolbox.register("evaluate", evaluate)
toolbox.register("clone", tools.clone_individual)
return toolbox
def print_results(toolbox, population, team):
tools.evaluate_invalid(toolbox, population)
matrix = tools.fitness_case_matrix(population)
best_single = max(solved_count(ind.fitness.values) for ind in population)
team_union = 0
team_matrix = tools.fitness_case_matrix(team)
for col in range(N_CASES):
if numpy.any(numpy.isclose(team_matrix[:, col], 0.0, atol=1e-12)):
team_union += 1
if team_union <= best_single:
raise RuntimeError(
f"Team coverage {team_union} did not beat the best single ({best_single})."
)
print(f"\nBest single solved {best_single} cases; team solved {team_union}.")
print(f"Packed matrix shape: {matrix.shape}")
def main():
toolbox = setup()
pop = toolbox.population(size=24)
tools.ea_simple(
toolbox,
pop,
generations=8,
cx_prob=0.5,
mut_prob=0.3,
verbose=True,
)
specialists = [creator.Individual([1, 0, 1]), creator.Individual([0, 1, 0])]
for ind in specialists:
ind.fitness.values = evaluate(ind)
pop.append(ind)
matrix = tools.fitness_case_matrix(pop)
team = tools.sel_team(pop, 2, matrix=matrix)
print_results(toolbox, pop, team)
if __name__ == "__main__":
main()