def test_recombine_two_parents(self): ind1 = Individual(None, [0.11, 0.12, 0.13], [0.011, 0.012, 0.013]) ind2 = Individual(None, [0.21, 0.22, 0.23], [0.021, 0.022, 0.023]) newborn = StandardRecombination.recombine([ind1, ind2]) self.assertTrue(np.equal([0.016, 0.017, 0.018], newborn.sigma).all())
def test_recombine_threes_parents(self): error = 1e-10 ind1 = Individual(None, [0.11, 0.12, 0.13, 0.14], [0.011, 0.012, 0.013, 0.014]) ind2 = Individual(None, [0.21, 0.22, 0.23, 0.24], [0.021, 0.022, 0.023, 0.024]) ind3 = Individual(None, [0.31, 0.32, 0.33, 0.3], [0.031, 0.032, 0.033, 0.034]) newborn = StandardRecombination.recombine([ind1, ind2, ind3]) self.assertTrue(np.abs(np.linalg.norm(newborn.sigma - [0.021, 0.022, 0.023, 0.024])) < error)
def test_remove_last_decrease_table_size_by_one(self): # insert two individuals self.table.add_individual(Individual(15.0, [2.0], [0.2])) self.table.add_individual(Individual(-15.0, [3.0], [0.3])) self.assertEquals(2, len(self.table)) self.table.remove_last() self.assertEquals(1, len(self.table))
def test_clear_sets_tablesize_to_zero(self): # insert two individuals self.table.add_individual(Individual(15.0, [2.0], [0.2])) self.table.add_individual(Individual(-15.0, [3.0], [0.3])) self.assertEquals(2, len(self.table)) self.table.clear() self.assertEquals(0, len(self.table))
def test_inserted_elements_are_sorted(self): # insert four individuals self.table.add_individual(Individual(15.0, [2.0], [0.2])) self.table.add_individual(Individual(-15.0, [3.0], [0.3])) self.table.add_individual(Individual(-30.0, [4.0], [0.4])) self.table.add_individual(Individual(15.0, [5.0], [0.5])) self.assertEqual(4, len(self.table)) for i in range(1, len(self.table)): self.assertTrue(self.table[i].fitness <= self.table[i-1].fitness)
def table_random_initialization(self, fitness_object): n_params = self.params_ngb.num_params initial_sigma = self.params_ngb.initial_sigma sigma_dim = n_params if self.params_ngb.is_sigma_array else 1 for i in range(0, self.params_ngb.initial_table_size): rnd_individ = Individual(None, np.random.uniform(0.0, 1.0, n_params), initial_sigma * np.ones(sigma_dim)) mapped_params = self.map_parameters(rnd_individ.params) # map params from (0.0, 1.0) -> search_space rnd_individ.fitness = fitness_object.compute(mapped_params) self.fitness_table.add_individual(rnd_individ)
def test_add_remove_individual_increases_size(self): size_initial = len(self.table) self.table.add_individual(Individual(5.0, [1.0], [0.1])) assert size_initial == 0 assert len(self.table) == 1
def test_after_mutation_parameters_are_within_zero_to_one_range(self): individual = Individual(None, 0.5 * np.ones(5), 0.3 * np.ones(5)) sigma_min = 0.01 sigma_max = 0.35 m = StandardMutation(len(individual.params), sigma_min, sigma_max) mutated_individual = m.mutate(individual) self.assertTrue((mutated_individual.params <= 1.0).all()) self.assertTrue((mutated_individual.params >= 0.0).all())
def mutate(self, individual): # mutate sigma array cmf = np.exp( self.tau0 * self.rnd_std_norm(1)) # common mutation factor for sigma vector sigma = cmf * individual.sigma * np.exp( self.tau1 * self.rnd_std_norm(len(individual.sigma))) # mutate parameters, use newly mutated sigma (important) params = individual.params + sigma * self.rnd_std_norm( len(individual.params)) # in case of overshooting: return parameters inside the range [0.0, 1.0] params[params < 0.0] = 0.0 params[params > 1.0] = 1.0 # in case of overshooting sigmas: return parameters inside the range [sigma_min, sigma_max] sigma[sigma < self.sigma_min] = self.sigma_min sigma[sigma > self.sigma_max] = self.sigma_max return Individual(individual.fitness, params, sigma)
def recombine(individuals): """As a result of the parents recombination a new child is produced. Each parameter of the newborn(recombined) individual represents a copy of one of the parent's. Parent for each parameter is chosen randomly. Sigma of the recombined individual is a simple average of all parents""" parents = len(individuals) params = np.zeros(len(individuals[0].params)) sigma = np.zeros(len(individuals[0].sigma)) # recombine parameters array for i in range(0, len(params)): idx = random.randint(0, parents - 1) params[i] = individuals[idx].params[i] # recombine sigma array for i in range(0, len(sigma)): for j in range(0, parents): sigma[i] += individuals[j].sigma[i] sigma /= parents return Individual(None, params, sigma)
def test_creation_of_individuals(self): individual = Individual(0.5, [-10.0, 20.0, 1000.0], [1.0, 0.5, 0.4]) self.assertEqual(0.5, individual.fitness) self.assertTrue(np.equal(np.array([-10.0, 20.0, 1000.0]), individual.params).all()) self.assertFalse(np.equal(np.array([-10.0, 20.1, 1000.0]), individual.params).all()) self.assertTrue(np.equal(np.array([1.0, 0.5, 0.4]),individual.sigma).all())
def test_create_individual_with_empty_sigma_throws(self): with self.assertRaises(ValueError): Individual(-1.0, [1.0, 2.0], [0.1, 0.2, 0.3])
def test_create_individual_with_empty_parameters_throws(self): with self.assertRaises(ValueError): Individual(-1.0, [], [1.0])
def test_create_individual_with_complex_fitness_throws(self): with self.assertRaises(ValueError): Individual(complex(1.0, 1.0), [1.0], [1.0])
def test_create_individual_with_nan_fitness_throws(self): with self.assertRaises(ValueError): Individual(math.inf, [1.0], [1.0])