def test_parameter_passing_e2e(self): class MyMember(ga.MemberBase): def _construct_from_params(self, construction_parameters=None): self.height = construction_parameters['height'] self.width = construction_parameters['width'] def mutate(self): i = random.randrange(2) j = random.randrange(2) self.height += pow(-1, i) self.width += pow(-1, j) def crossover(self, pairing): new_params = { 'height': np.mean([self.height, pairing.height]), 'width': np.mean([self.width, pairing.width]) } return MyMember(construction_parameters=new_params) def fit_through_door(member: MyMember): door_height = 10 door_width = 3 height_diff = abs(door_height - member.height) width_diff = abs(door_width - member.width) return height_diff + width_diff def param_generator(): max_h = 10 max_w = 20 yield { 'height': random.randrange(max_h), 'width': random.randrange(max_w) } random.seed(1) pop = ga.Population(10, MyMember, fit_through_door, member_parameters_generator=param_generator) self.assertEqual(len(pop.population), 10) self.assertEqual(pop.member_type, MyMember) self.assertEqual(pop.fitness_function, fit_through_door) self.assertDictEqual(pop.population[0].construction_parameters, { 'height': 2, 'width': 18 }) # run 5 generations before checking we have some parameters changed pop.run(generations=500, maximise_fitness_func=False) self.assertEqual({ 'height': 9.6953125, 'width': 4.1953125 }, pop.population[0].construction_parameters)
def test_creation_basic(self): class MyMember(ga.MemberBase): def _construct_from_params(self, construction_parameters=None): self.vars = [random.randrange(10) for _ in range(10)] # Create mutate and score are not needed for creation def mutate(self): pass def crossover(self, pairing): pass def score_self(self): pass pop = ga.Population(10, MyMember, MyMember.score_self) self.assertEqual(len(pop.population), 10) self.assertEqual(pop.member_type, MyMember) self.assertEqual(pop.fitness_function, MyMember.score_self)
def test_e2e_basic(self): class MyMember(ga.MemberBase): def _construct_from_params(self, construction_parameters=None): self.vars = [random.randrange(10) for _ in range(10)] def mutate(self): j = random.randrange(len(self.vars)) self.vars[j] += 1 def crossover(self, pairing): new_params = self.vars[:len(self.vars) // 2] + pairing.vars[len(pairing.vars) // 2:] return MyMember(new_params) def score_self(self): return sum(self.vars) def m_fit_func(member: MyMember): return member.score_self() pop = ga.Population(size=10, member_type=MyMember, member_parameters_generator=None, fitness_function=m_fit_func, population_seed=0) start_pop = pop.population start_scores = list(starmap(m_fit_func, [[m] for m in start_pop])) # Ensure good creation self.assertEqual(len(pop.population), 10) self.assertEqual(pop.member_type, MyMember) self.assertEqual(pop.fitness_function, m_fit_func) pop.run(10, print_logging=False, maximise_fitness_func=True) end_scores = list(starmap(m_fit_func, [[m] for m in pop.population])) # Ensure changes have been made self.assertNotEqual(pop.population, start_pop) self.assertGreaterEqual(max(end_scores), max(start_scores))
class MyMember(ga.MemberBase): def _construct_from_params(self, construction_parameters=None): self.vars = [random.randrange(10) for _ in range(5)] def mutate(self): # i = random.randrange(len(self.vars)) j = random.randrange(len(self.vars)) # tmp = self.vars[i] # self.vars[i] = self.vars[j] self.vars[j] += 1 def crossover(self, pairing): new_params = self.vars[:len(self.vars) // 2] + pairing.vars[len(pairing.vars) // 2:] return MyMember(new_params) def score_self(self): return sum(self.vars) def m_fit_func(member: MyMember): return member.score_self() pop = ga.Population(size=10, member_type=MyMember, member_parameters_generator=None, fitness_function=m_fit_func, population_seed=0) pop.run(100, print_logging=True, csv_path="example1.csv")
if height_diff > 0 and width_diff > 0: return (1 / height_diff) + (1 / width_diff) elif height_diff == 0: return 1 / width_diff elif width_diff == 0: return 1 / height_diff else: return np.inf def param_generator(): max_h = 10 max_w = 20 yield {'height': random.randrange(max_h), 'width': random.randrange(max_w)} random.seed(1) pop = ga.Population(100, Door, fit_through_door, member_parameters_generator=param_generator) # run 500 generations before checking we have some parameters changed pop.run( generations=500, print_logging=True, ) print("Best door:", pop.get_top()) # This will spit out a very close approximation of the true door size we selected