def test_generate_chromosome(self): """ Tests generate_chromosome() method. """ param_values = deepcopy(self.default_param_values) brkga = BrkgaMpIpr(**param_values) local_rng = Random(param_values["seed"]) # Same warm up that the one in the constructor. for _ in range(1000): local_rng.random() self.assertEqual(brkga._rng.getstate(), local_rng.getstate()) size = param_values["chromosome_size"] standard = BaseChromosome([local_rng.random() for _ in range(size)]) new_chr = brkga.generate_chromosome(size) self.assertEqual(len(new_chr), size) self.assertEqual(new_chr, standard) size = 1000 standard = BaseChromosome([local_rng.random() for _ in range(size)]) new_chr = brkga.generate_chromosome(size) self.assertEqual(len(new_chr), size) self.assertEqual(new_chr, standard)
def test_exchange_elite(self): """ Tests exchange_elite() method. """ param_values = deepcopy(self.default_param_values) brkga = BrkgaMpIpr(**param_values) self.assertRaises(NotImplementedError, brkga.exchange_elite, 0)
def test__direct_path_relink(self): """ Tests _direct_path_relink() method. """ param_values = deepcopy(self.default_param_values) brkga = BrkgaMpIpr(**param_values) self.assertRaises(NotImplementedError, brkga._direct_path_relink, None, None, None, None, 0, 0, 0.0)
def test_shake(self): """ Tests shake() method. """ param_values = deepcopy(self.default_param_values) brkga = BrkgaMpIpr(**param_values) self.assertRaises(NotImplementedError, brkga.shake, 0, ShakingType.SWAP, 0)
def test_inject_chromosome(self): """ Tests inject_chromosome() method. """ param_values = deepcopy(self.default_param_values) brkga = BrkgaMpIpr(**param_values) self.assertRaises(NotImplementedError, brkga.inject_chromosome, BaseChromosome(), 0, 0, 0)
def test_fill_chromosome(self): """ Tests fill_chromosome() method. """ param_values = deepcopy(self.default_param_values) brkga = BrkgaMpIpr(**param_values) local_rng = Random(param_values["seed"]) # Same warm up that the one in the constructor. for _ in range(1000): local_rng.random() self.assertEqual(brkga._rng.getstate(), local_rng.getstate()) size = param_values["chromosome_size"] chromosome = BaseChromosome([0.0 for _ in range(size)]) old_chrmosome = deepcopy(chromosome) brkga.fill_chromosome(chromosome) local_chr = BaseChromosome([local_rng.random() for _ in range(size)]) self.assertEqual(len(chromosome), len(old_chrmosome)) self.assertNotEqual(chromosome, old_chrmosome) self.assertEqual(chromosome, local_chr) size = 1000 chromosome = BaseChromosome([0.0 for _ in range(size)]) old_chrmosome = deepcopy(chromosome) brkga.fill_chromosome(chromosome) local_chr = BaseChromosome([local_rng.random() for _ in range(size)]) self.assertEqual(len(chromosome), len(old_chrmosome)) self.assertNotEqual(chromosome, old_chrmosome) self.assertEqual(chromosome, local_chr)
def main() -> None: if len(sys.argv) < 4: print("Usage: python main_minimal.py <seed> <config-file> " "<num-generations> <tsp-instance-file>") sys.exit(1) ######################################## # Read the command-line arguments and the instance ######################################## seed = int(sys.argv[1]) configuration_file = sys.argv[2] num_generations = int(sys.argv[3]) instance_file = sys.argv[4] print("Reading data...") instance = TSPInstance(instance_file) ######################################## # Read algorithm parameters ######################################## print("Reading parameters...") brkga_params, _ = load_configuration(configuration_file) ######################################## # Build the BRKGA data structures and initialize ######################################## print("Building BRKGA data and initializing...") decoder = TSPDecoder(instance) brkga = BrkgaMpIpr(decoder=decoder, sense=Sense.MINIMIZE, seed=seed, chromosome_size=instance.num_nodes, params=brkga_params) # NOTE: don't forget to initialize the algorithm. brkga.initialize() ######################################## # Find good solutions / evolve ######################################## print(f"Evolving {num_generations} generations...") brkga.evolve(num_generations) best_cost = brkga.get_best_fitness() print(f"Best cost: {best_cost}")
def test_reset(self): """ Tests reset() method. """ param_values = deepcopy(self.default_param_values) params = param_values["params"] brkga = BrkgaMpIpr(**param_values) with self.assertRaises(RuntimeError) as context: brkga.reset() self.assertEqual(str(context.exception).strip(), "The algorithm hasn't been initialized. " "Call 'initialize()' before 'reset()'") brkga.initialize() # Create a local RNG and advance it until the same state as the # internal BRKGA RNG after initialization. local_rng = Random(param_values["seed"]) skip = 1000 + params.num_independent_populations * \ params.population_size * brkga.chromosome_size for _ in range(skip): local_rng.random() # Assert the both generators are in the same state. self.assertEqual(brkga._rng.getstate(), local_rng.getstate()) # Create a local chromosome and applied the decoder on it. local_chr = BaseChromosome([ local_rng.random() for _ in range(param_values["chromosome_size"]) ]) param_values["decoder"].decode(local_chr, rewrite=True) # Reset and test the first individual. brkga.reset() self.assertEqual(brkga._current_populations[0].chromosomes[0], local_chr) # After reset, the reset phase flag should be deactivated. self.assertFalse(brkga._reset_phase)
def test_get_best_fitness(self): """ Tests get_best_fitness() method. """ param_values = deepcopy(self.default_param_values) param_values["sense"] = Sense.MAXIMIZE param_values["seed"] = 12323 param_values["chromosome_size"] = self.chromosome_size param_values["params"].population_size = 500 param_values["params"].num_independent_populations = 3 params = param_values["params"] brkga = BrkgaMpIpr(**param_values) # Not initialized with self.assertRaises(RuntimeError) as context: brkga.get_best_fitness() self.assertEqual(str(context.exception).strip(), "The algorithm hasn't been initialized. " "Call 'initialize()' before 'get_best_fitness()'") brkga.initialize() ######################## # Test for maximization ######################## local_rng = Random(param_values["seed"]) for _ in range(1000): local_rng.random() num_individuals = params.population_size * \ params.num_independent_populations best_value = -math.inf for _ in range(num_individuals): local_chr = BaseChromosome([ local_rng.random() for _ in range(param_values["chromosome_size"]) ]) best_value = max( best_value, self.sum_decoder.decode(local_chr, True) ) # Assert the both generators are in the same state. self.assertEqual(brkga._rng.getstate(), local_rng.getstate()) # Test the actual value. self.assertAlmostEqual(brkga.get_best_fitness(), best_value) ######################## # Test for minimization ######################## param_values["sense"] = Sense.MINIMIZE brkga = BrkgaMpIpr(**param_values) brkga.initialize() local_rng = Random(param_values["seed"]) for _ in range(1000): local_rng.random() num_individuals = params.population_size * \ params.num_independent_populations best_value = math.inf for _ in range(num_individuals): local_chr = BaseChromosome([ local_rng.random() for _ in range(param_values["chromosome_size"]) ]) best_value = min( best_value, self.sum_decoder.decode(local_chr, True) ) # Assert the both generators are in the same state. self.assertEqual(brkga._rng.getstate(), local_rng.getstate()) # Test the actual value. self.assertAlmostEqual(brkga.get_best_fitness(), best_value)
def test_get_current_population(self): """ Tests get_current_population() method. """ param_values = deepcopy(self.default_param_values) param_values["params"].num_independent_populations = 3 params = param_values["params"] brkga = BrkgaMpIpr(**param_values) # Not initialized with self.assertRaises(RuntimeError) as context: brkga.get_current_population() self.assertEqual(str(context.exception).strip(), "The algorithm hasn't been initialized. " "Call 'initialize()' before 'get_current_population()'") brkga.initialize() # Test invalid population indices. population_index = -1 with self.assertRaises(ValueError) as context: brkga.get_current_population(population_index) self.assertEqual(str(context.exception).strip(), "Population must be in [0, 2]: -1") population_index = brkga.params.num_independent_populations with self.assertRaises(ValueError) as context: brkga.get_current_population(population_index) self.assertEqual(str(context.exception).strip(), "Population must be in [0, 2]: 3") # Test if it is returning the right population. for i in range(params.num_independent_populations): self.assertIs(brkga.get_current_population(i), brkga._current_populations[i])
def test_get_chromosome(self): """ Tests get_chromosome() method. """ param_values = deepcopy(self.default_param_values) param_values["params"].num_independent_populations = 3 params = param_values["params"] brkga = BrkgaMpIpr(**param_values) # Not initialized with self.assertRaises(RuntimeError) as context: brkga.get_chromosome(0, 0) self.assertEqual(str(context.exception).strip(), "The algorithm hasn't been initialized. " "Call 'initialize()' before 'get_chromosome()'") brkga.initialize() # Test invalid population indices. population_index = -1 position = 0 with self.assertRaises(ValueError) as context: brkga.get_chromosome(population_index, position) self.assertEqual(str(context.exception).strip(), "Population must be in [0, 2]: -1") population_index = brkga.params.num_independent_populations position = 0 with self.assertRaises(ValueError) as context: brkga.get_chromosome(population_index, position) self.assertEqual(str(context.exception).strip(), "Population must be in [0, 2]: 3") # Test invalid chrmosome indices. population_index = 0 position = -1 with self.assertRaises(ValueError) as context: brkga.get_chromosome(population_index, position) self.assertEqual(str(context.exception).strip(), "Chromosome position must be in [0, 9]: -1") population_index = 0 position = brkga.params.population_size with self.assertRaises(ValueError) as context: brkga.get_chromosome(population_index, position) self.assertEqual(str(context.exception).strip(), "Chromosome position must be in [0, 9]: 10") # Test if the chromosome matches. # Create a local RNG and advance it until the same state as the # internal BRKGA RNG after initialization. local_rng = Random(param_values["seed"]) skip = 1000 for _ in range(skip): local_rng.random() # Now, we create the populations, decode them, and sort the # individuals according to their fitness, reproducing initialize() # basically. local_populations = [] for _ in range(brkga.params.num_independent_populations): population = [] for _ in range(brkga.params.population_size): local_chr = BaseChromosome([ local_rng.random() for _ in range(param_values["chromosome_size"]) ]) fitness = brkga._decoder.decode(local_chr, True) population.append((fitness, local_chr)) # end for population.sort(reverse=(brkga.opt_sense == Sense.MAXIMIZE)) local_populations.append(population) # end for # Assert the both generators are in the same state. self.assertEqual(brkga._rng.getstate(), local_rng.getstate()) population_index = 0 position = 0 copy_chr = brkga.get_chromosome(population_index, position) self.assertEqual(copy_chr, local_populations[population_index][position][1]) self.assertIsNot(copy_chr, local_populations[population_index][position][1]) population_index = 1 position = 1 copy_chr = brkga.get_chromosome(population_index, position) self.assertEqual(copy_chr, local_populations[population_index][position][1]) self.assertIsNot(copy_chr, local_populations[population_index][position][1]) population_index = brkga.params.num_independent_populations - 1 position = brkga.params.population_size - 1 copy_chr = brkga.get_chromosome(population_index, position) self.assertEqual(copy_chr, local_populations[population_index][position][1]) self.assertIsNot(copy_chr, local_populations[population_index][position][1])
def main() -> None: """ Proceeds with the optimization. Create to avoid spread `global` keywords around the code. """ args = docopt.docopt(__doc__) # print(args) configuration_file = args["--config_file"] instance_file = args["--instance_file"] seed = int(args["--seed"]) stop_rule = StopRule(args["--stop_rule"]) if stop_rule == StopRule.TARGET: stop_argument = float(args["--stop_arg"]) else: stop_argument = int(args["--stop_arg"]) maximum_time = float(args["--max_time"]) if maximum_time <= 0.0: raise RuntimeError(f"Maximum time must be larger than 0.0. " f"Given {maximum_time}.") perform_evolution = not args["--no_evolution"] ######################################## # Load config file and show basic info. ######################################## brkga_params, control_params = load_configuration(configuration_file) print(f"""------------------------------------------------------ > Experiment started at {datetime.now()} > Instance: {instance_file} > Configuration: {configuration_file} > Algorithm Parameters:""", end="") if not perform_evolution: print("> - Simple multi-start: on (no evolutionary operators)") else: output_string = "" for name, value in vars(brkga_params).items(): output_string += f"\n> -{name} {value}" for name, value in vars(control_params).items(): output_string += f"\n> -{name} {value}" print(output_string) print(f"""> Seed: {seed} > Stop rule: {stop_rule} > Stop argument: {stop_argument} > Maximum time (s): {maximum_time} ------------------------------------------------------""") ######################################## # Load instance and adjust BRKGA parameters ######################################## print(f"\n[{datetime.now()}] Reading TSP data...") instance = TSPInstance(instance_file) print(f"Number of nodes: {instance.num_nodes}") print(f"\n[{datetime.now()}] Generating initial tour...") # Generate a greedy solution to be used as warm start for BRKGA. initial_cost, initial_tour = greedy_tour(instance) print(f"Initial cost: {initial_cost}") ######################################## # Build the BRKGA data structures and initialize ######################################## print(f"\n[{datetime.now()}] Building BRKGA data...") # Usually, it is a good idea to set the population size # proportional to the instance size. brkga_params.population_size = min(brkga_params.population_size, 10 * instance.num_nodes) print(f"New population size: {brkga_params.population_size}") # Build a decoder object. decoder = TSPDecoder(instance) # Chromosome size is the number of nodes. # Each chromosome represents a permutation of nodes. brkga = BrkgaMpIpr(decoder=decoder, sense=Sense.MINIMIZE, seed=seed, chromosome_size=instance.num_nodes, params=brkga_params, evolutionary_mechanism_on=perform_evolution) # To inject the initial tour, we need to create chromosome representing # that solution. First, we create a set of keys to be used in the # chromosome. random.seed(seed) keys = sorted([random.random() for _ in range(instance.num_nodes)]) # Then, we visit each node in the tour and assign to it a key. initial_chromosome = [0] * instance.num_nodes for i in range(instance.num_nodes): initial_chromosome[initial_tour[i]] = keys[i] # Inject the warm start solution in the initial population. brkga.set_initial_population([initial_chromosome]) # NOTE: don't forget to initialize the algorithm. print(f"\n[{datetime.now()}] Initializing BRKGA data...") brkga.initialize() ######################################## # Warm up the script/code ######################################## # To make sure we are timing the runs correctly, we run some warmup # iterations with bogus data. Warmup is always recommended for script # languages. Here, we call the most used methods. print(f"\n[{datetime.now()}] Warming up...") bogus_alg = deepcopy(brkga) bogus_alg.evolve(2) # TODO (ceandrade): warm up path relink functions. # bogus_alg.path_relink(brkga_params.pr_type, brkga_params.pr_selection, # (x, y) -> 1.0, (x, y) -> true, 0, 0.5, 1, 10.0, 1.0) bogus_alg.get_best_fitness() bogus_alg.get_best_chromosome() bogus_alg = None ######################################## # Evolving ######################################## print(f"\n[{datetime.now()}] Evolving...") print("* Iteration | Cost | CurrentTime") best_cost = initial_cost * 2 best_chromosome = initial_chromosome iteration = 0 last_update_time = 0.0 last_update_iteration = 0 large_offset = 0 # TODO (ceandrade): enable the following when path relink is ready. # path_relink_time = 0.0 # num_path_relink_calls = 0 # num_homogenities = 0 # num_best_improvements = 0 # num_elite_improvements = 0 run = True # Main optimization loop. We evolve one generation at time, # keeping track of all changes during such process. start_time = time.time() while run: iteration += 1 # Evolves one iteration. brkga.evolve() # Checks the current results and holds the best. fitness = brkga.get_best_fitness() if fitness < best_cost: last_update_time = time.time() - start_time update_offset = iteration - last_update_iteration if large_offset < update_offset: large_offset = update_offset last_update_iteration = iteration best_cost = fitness best_chromosome = brkga.get_best_chromosome() print(f"* {iteration} | {best_cost:.0f} | {last_update_time:.2f}") # end if # TODO (ceandrade): implement path relink calls here. # Please, see Julia version for that. iter_without_improvement = iteration - last_update_iteration # Check stop criteria. run = not ( (time.time() - start_time > maximum_time) or (stop_rule == StopRule.GENERATIONS and iteration == stop_argument) or (stop_rule == StopRule.IMPROVEMENT and iter_without_improvement >= stop_argument) or (stop_rule == StopRule.TARGET and best_cost <= stop_argument)) # end while total_elapsed_time = time.time() - start_time total_num_iterations = iteration print(f"[{datetime.now()}] End of optimization\n") print(f"Total number of iterations: {total_num_iterations}") print(f"Last update iteration: {last_update_iteration}") print(f"Total optimization time: {total_elapsed_time:.2f}") print(f"Last update time: {last_update_time:.2f}") print(f"Large number of iterations between improvements: {large_offset}") # TODO (ceandrade): enable when path relink is ready. # print(f"\nTotal path relink time: {path_relink_time:.2f}") # print(f"\nTotal path relink calls: {num_path_relink_calls}") # print(f"\nNumber of homogenities: {num_homogenities}") # print(f"\nImprovements in the elite set: {num_elite_improvements}") # print(f"\nBest individual improvements: {num_best_improvements}") ######################################## # Extracting the best tour ######################################## tour = [] for (index, key) in enumerate(best_chromosome): tour.append((key, index)) tour.sort() print(f"\n% Best tour cost: {best_cost:.2f}") print("% Best tour: ", end="") for _, node in tour: print(node, end=" ") print( "\n\nInstance,Seed,NumNodes,TotalIterations,TotalTime," #"TotalPRTime,PRCalls,NumHomogenities,NumPRImprovElite," #"NumPrImprovBest," "LargeOffset,LastUpdateIteration,LastUpdateTime," "Cost") print( f"{basename(instance_file)}," f"{seed},{instance.num_nodes},{total_num_iterations}," f"{total_elapsed_time:.2f}," # f"{path_relink_time:.2f},{num_path_relink_calls}," # f"{num_homogenities},{num_elite_improvements},{num_best_improvements}," f"{large_offset},{last_update_iteration}," f"{last_update_time:.2f},{best_cost:.0f}")
def gen_conf1(): param_values = deepcopy(default_param_values) brkga_params = param_values["params"] brkga_params.population_size = 100 brkga_params.elite_percentage = 0.3 brkga_params.mutants_percentage = 0.1 brkga_params.num_elite_parents = 1 brkga_params.total_parents = 2 brkga_params.bias_type = BiasFunctionType.LOGINVERSE brkga_params.num_independent_populations = 1 brkga_params.pr_number_pairs = 0 brkga_params.pr_minimum_distance = 0.0 brkga_params.pr_type = PathRelinkingType.DIRECT brkga_params.pr_selection = PathRelinkingSelection.BESTSOLUTION brkga_params.alpha_block_size = 1.0 brkga_params.pr_percentage = 1.0 param_values["decoder"] = sum_decoder param_values["sense"] = Sense.MAXIMIZE param_values["seed"] = 4013750229 param_values["chromosome_size"] = chromosome_size param_values["evolutionary_mechanism_on"] = True print("\n> Building configuration 1") brkga = BrkgaMpIpr(**param_values) brkga.initialize() print("> Writing configuration 1") with open(os.path.join(STATE_DIR, "state1.pickle"), "wb") as hd: pickle.dump(brkga, hd) print("> Evolving population 0") brkga.evolve_population(0) fitness1 = brkga.get_best_fitness() chromosome1 = brkga.get_best_chromosome() brkga.evolve_population(0) fitness2 = brkga.get_best_fitness() chromosome2 = brkga.get_best_chromosome() for _ in range(100): brkga.evolve_population(0) fitness102 = brkga.get_best_fitness() chromosome102 = brkga.get_best_chromosome() with open(os.path.join(SOLUTION_DIR, "best_solution1.pickle"), "wb") as hd: pickle.dump( { "fitness1": fitness1, "chromosome1": chromosome1, "fitness2": fitness2, "chromosome2": chromosome2, "fitness102": fitness102, "chromosome102": chromosome102, }, hd )
def gen_conf5(): param_values = deepcopy(default_param_values) brkga_params = param_values["params"] chromosome_size = 100 instance = Instance(chromosome_size) brkga_params.population_size = 100 brkga_params.elite_percentage = 0.30 brkga_params.mutants_percentage = 0.20 brkga_params.num_elite_parents = 2 brkga_params.total_parents = 3 brkga_params.bias_type = BiasFunctionType.LOGINVERSE brkga_params.num_independent_populations = 3 brkga_params.pr_number_pairs = 0 brkga_params.pr_minimum_distance = 0.0 brkga_params.pr_type = PathRelinkingType.DIRECT brkga_params.pr_selection = PathRelinkingSelection.BESTSOLUTION brkga_params.alpha_block_size = 1.0 brkga_params.pr_percentage = 1.0 param_values["decoder"] = SumDecode(instance) param_values["sense"] = Sense.MINIMIZE param_values["seed"] = 4659930950303 param_values["chromosome_size"] = chromosome_size param_values["evolutionary_mechanism_on"] = True print("\n> Building configuration 5") brkga = BrkgaMpIpr(**param_values) brkga.initialize() print("> Writing configuration 5") with open(os.path.join(STATE_DIR, "state5.pickle"), "wb") as hd: pickle.dump(brkga, hd) print("> Evolving one generation...") brkga.evolve() fitness1 = brkga.get_best_fitness() chromosome1 = brkga.get_best_chromosome() print("> Evolving 10 generations...") brkga.evolve(10) fitness10 = brkga.get_best_fitness() chromosome10 = brkga.get_best_chromosome() print("> Evolving 100 generations...") brkga.evolve(100) fitness100 = brkga.get_best_fitness() chromosome100 = brkga.get_best_chromosome() with open(os.path.join(SOLUTION_DIR, "best_solution5.pickle"), "wb") as hd: pickle.dump( { "fitness1": fitness1, "chromosome1": chromosome1, "fitness10": fitness10, "chromosome10": chromosome10, "fitness100": fitness100, "chromosome100": chromosome100 }, hd ) print("fitness", fitness1) print("fitness", fitness10) print("fitness", fitness100)
def gen_conf4(): param_values = deepcopy(default_param_values) brkga_params = param_values["params"] chromosome_size = 500 instance = Instance(chromosome_size) brkga_params.population_size = 100 brkga_params.elite_percentage = 0.35 brkga_params.mutants_percentage = 0.15 brkga_params.num_elite_parents = 1 brkga_params.total_parents = 2 brkga_params.bias_type = BiasFunctionType.EXPONENTIAL brkga_params.num_independent_populations = 3 brkga_params.pr_number_pairs = 0 brkga_params.pr_minimum_distance = 0.0 brkga_params.pr_type = PathRelinkingType.DIRECT brkga_params.pr_selection = PathRelinkingSelection.BESTSOLUTION brkga_params.alpha_block_size = 1.0 brkga_params.pr_percentage = 1.0 param_values["decoder"] = SumDecode(instance) param_values["sense"] = Sense.MINIMIZE param_values["seed"] = 2947804214761 param_values["chromosome_size"] = chromosome_size param_values["evolutionary_mechanism_on"] = True print("\n> Building configuration 4") brkga = BrkgaMpIpr(**param_values) brkga.initialize() rho = 0.75 brkga.set_bias_custom_function(lambda x: rho if x == 1 else 1.0 - rho) print("> Writing configuration 4") with open(os.path.join(STATE_DIR, "state4.pickle"), "wb") as hd: pickle.dump(brkga, hd) print("> Evolving population 0...") brkga.evolve_population(0) fitness1 = brkga.get_best_fitness() chromosome1 = brkga.get_best_chromosome() print("> Evolving population 1...") brkga.evolve_population(1) fitness2 = brkga.get_best_fitness() chromosome2 = brkga.get_best_chromosome() print("> Evolving population 2...") brkga.evolve_population(2) fitness3 = brkga.get_best_fitness() chromosome3 = brkga.get_best_chromosome() print("> Evolving both populations for 100 generations...") for _ in range(100): start_time = time() brkga.evolve_population(0) brkga.evolve_population(1) brkga.evolve_population(2) print(f"Elapsed time: {time() - start_time :.2f}") fitness103 = brkga.get_best_fitness() chromosome103 = brkga.get_best_chromosome() with open(os.path.join(SOLUTION_DIR, "best_solution4.pickle"), "wb") as hd: pickle.dump( { "fitness1": fitness1, "chromosome1": chromosome1, "fitness2": fitness2, "chromosome2": chromosome2, "fitness3": fitness2, "chromosome3": chromosome2, "fitness103": fitness103, "chromosome103": chromosome103, }, hd )
def gen_conf3(): param_values = deepcopy(default_param_values) brkga_params = param_values["params"] chromosome_size = 500 instance = Instance(chromosome_size) brkga_params.population_size = 100 brkga_params.elite_percentage = 0.35 brkga_params.mutants_percentage = 0.17 brkga_params.num_elite_parents = 3 brkga_params.total_parents = 5 brkga_params.bias_type = BiasFunctionType.EXPONENTIAL brkga_params.num_independent_populations = 5 brkga_params.pr_number_pairs = 0 brkga_params.pr_minimum_distance = 0.0 brkga_params.pr_type = PathRelinkingType.DIRECT brkga_params.pr_selection = PathRelinkingSelection.BESTSOLUTION brkga_params.alpha_block_size = 1.0 brkga_params.pr_percentage = 1.0 param_values["decoder"] = SumDecode(instance) param_values["sense"] = Sense.MINIMIZE param_values["seed"] = 253624607406 param_values["chromosome_size"] = chromosome_size param_values["evolutionary_mechanism_on"] = True print("\n> Building configuration 3") brkga = BrkgaMpIpr(**param_values) brkga.initialize() print("> Writing configuration 3") with open(os.path.join(STATE_DIR, "state3.pickle"), "wb") as hd: pickle.dump(brkga, hd) print("> Evolving both populations for one generation...") for i in range(brkga_params.num_independent_populations): brkga.evolve_population(i) fitness1 = brkga.get_best_fitness() chromosome1 = brkga.get_best_chromosome() print("> Evolving both populations for another generation...") for i in range(brkga_params.num_independent_populations): brkga.evolve_population(i) brkga.evolve_population(1) fitness2 = brkga.get_best_fitness() chromosome2 = brkga.get_best_chromosome() print("> Evolving both populations for 100 generations...") for _ in range(100): start_time = time() for i in range(brkga_params.num_independent_populations): brkga.evolve_population(i) print(f"Elapsed time: {time() - start_time :.2f}") fitness102 = brkga.get_best_fitness() chromosome102 = brkga.get_best_chromosome() with open(os.path.join(SOLUTION_DIR, "best_solution3.pickle"), "wb") as hd: pickle.dump( { "fitness1": fitness1, "chromosome1": chromosome1, "fitness2": fitness2, "chromosome2": chromosome2, "fitness102": fitness102, "chromosome102": chromosome102, }, hd ) print("fitness", fitness1) # print("chromosome", chromosome1) print("fitness", fitness2) # print("chromosome", chromosome2) print("fitness", fitness102)
def gen_conf2(): param_values = deepcopy(default_param_values) brkga_params = param_values["params"] chromosome_size = 1000 instance = Instance(chromosome_size) brkga_params.population_size = 500 brkga_params.elite_percentage = 0.25 brkga_params.mutants_percentage = 0.25 brkga_params.num_elite_parents = 5 brkga_params.total_parents = 50 brkga_params.bias_type = BiasFunctionType.QUADRATIC brkga_params.num_independent_populations = 2 brkga_params.pr_number_pairs = 0 brkga_params.pr_minimum_distance = 0.0 brkga_params.pr_type = PathRelinkingType.DIRECT brkga_params.pr_selection = PathRelinkingSelection.BESTSOLUTION brkga_params.alpha_block_size = 1.0 brkga_params.pr_percentage = 1.0 param_values["decoder"] = RankDecode(instance) param_values["sense"] = Sense.MINIMIZE param_values["seed"] = 1297832326904308 param_values["chromosome_size"] = chromosome_size param_values["evolutionary_mechanism_on"] = True print("\n> Building configuration 2") brkga = BrkgaMpIpr(**param_values) brkga.initialize() print("> Writing configuration 2") with open(os.path.join(STATE_DIR, "state2.pickle"), "wb") as hd: pickle.dump(brkga, hd) print("> Evolving population 0...") brkga.evolve_population(0) fitness1 = brkga.get_best_fitness() chromosome1 = brkga.get_best_chromosome() print("> Evolving population 1...") brkga.evolve_population(1) fitness2 = brkga.get_best_fitness() chromosome2 = brkga.get_best_chromosome() print("> Evolving both populations for 100 generations...") for _ in range(100): start_time = time() brkga.evolve_population(0) brkga.evolve_population(1) print(f"Elapsed time: {time() - start_time :.2f}") fitness102 = brkga.get_best_fitness() chromosome102 = brkga.get_best_chromosome() with open(os.path.join(SOLUTION_DIR, "best_solution2.pickle"), "wb") as hd: pickle.dump( { "fitness1": fitness1, "chromosome1": chromosome1, "fitness2": fitness2, "chromosome2": chromosome2, "fitness102": fitness102, "chromosome102": chromosome102, }, hd )
def test_set_initial_population(self): """ Tests set_initial_population() method. """ param_values = deepcopy(self.default_param_values) param_values["chromosome_size"] = 3 param_values["params"].num_independent_populations = 2 brkga = BrkgaMpIpr(**param_values) local_rng = Random(param_values["seed"]) chromosomes = [ BaseChromosome() for _ in range(brkga.params.population_size + 1) ] with self.assertRaises(ValueError) as context: brkga.set_initial_population(chromosomes) self.assertEqual( str(context.exception).strip(), "Number of given chromosomes (11) is large than " "the population size (10)") chromosomes = [ BaseChromosome([ local_rng.random() for _ in range(param_values["chromosome_size"] + 1) ]) ] with self.assertRaises(ValueError) as context: brkga.set_initial_population(chromosomes) self.assertEqual( str(context.exception).strip(), "Error on setting initial population: chromosome 0 " "does not have the required dimension " "(actual size: 4, required size: 3)") chromosomes = [ BaseChromosome([ local_rng.random() for _ in range(param_values["chromosome_size"] - 1) ]) ] with self.assertRaises(ValueError) as context: brkga.set_initial_population(chromosomes) self.assertEqual( str(context.exception).strip(), "Error on setting initial population: chromosome 0 " "does not have the required dimension " "(actual size: 2, required size: 3)") chromosomes = [ BaseChromosome([ local_rng.random() for _ in range(param_values["chromosome_size"] + 1) ]), BaseChromosome([ local_rng.random() for _ in range(param_values["chromosome_size"]) ]), BaseChromosome([ local_rng.random() for _ in range(param_values["chromosome_size"]) ]) ] with self.assertRaises(ValueError) as context: brkga.set_initial_population(chromosomes) self.assertEqual( str(context.exception).strip(), "Error on setting initial population: chromosome 0 " "does not have the required dimension " "(actual size: 4, required size: 3)") chromosomes = [ BaseChromosome([ local_rng.random() for _ in range(param_values["chromosome_size"]) ]), BaseChromosome([ local_rng.random() for _ in range(param_values["chromosome_size"] + 1) ]), BaseChromosome([ local_rng.random() for _ in range(param_values["chromosome_size"]) ]) ] with self.assertRaises(ValueError) as context: brkga.set_initial_population(chromosomes) self.assertEqual( str(context.exception).strip(), "Error on setting initial population: chromosome 1 " "does not have the required dimension " "(actual size: 4, required size: 3)") chromosomes = [ BaseChromosome([ local_rng.random() for _ in range(param_values["chromosome_size"]) ]), BaseChromosome([ local_rng.random() for _ in range(param_values["chromosome_size"]) ]), BaseChromosome([ local_rng.random() for _ in range(param_values["chromosome_size"] + 1) ]) ] with self.assertRaises(ValueError) as context: brkga.set_initial_population(chromosomes) self.assertEqual( str(context.exception).strip(), "Error on setting initial population: chromosome 2 " "does not have the required dimension " "(actual size: 4, required size: 3)") chromosomes = [ BaseChromosome([ local_rng.random() for _ in range(param_values["chromosome_size"]) ]) ] brkga.set_initial_population(chromosomes) self.assertEqual(brkga._current_populations[0].chromosomes[0], chromosomes[0]) self.assertIsNot(brkga._current_populations[0].chromosomes[0], chromosomes[0]) chromosomes[0] = BaseChromosome([0.1111, 0.2222, 0.3333]) self.assertNotEqual(brkga._current_populations[0].chromosomes[0], chromosomes[0]) chromosomes = [ BaseChromosome([ local_rng.random() for _ in range(param_values["chromosome_size"]) ]), BaseChromosome([ local_rng.random() for _ in range(param_values["chromosome_size"]) ]), BaseChromosome([ local_rng.random() for _ in range(param_values["chromosome_size"]) ]) ] brkga.set_initial_population(chromosomes) self.assertEqual(len(brkga._current_populations[0].chromosomes), len(chromosomes)) self.assertEqual(brkga._current_populations[0].chromosomes, chromosomes) self.assertIsNot(brkga._current_populations[0].chromosomes, chromosomes) self.assertEqual(brkga._initial_population, True)
def test_set_bias_custom_function(self): """ Tests set_bias_custom_function() method. """ param_values = deepcopy(self.default_param_values) param_values["params"].population_size = 100 param_values["params"].total_parents = 10 brkga = BrkgaMpIpr(**param_values) # After build, brkga_params function is never CUSTOM self.assertNotEqual(brkga.params.bias_type, BiasFunctionType.CUSTOM) with self.assertRaises(ValueError) as context: brkga.set_bias_custom_function(lambda x: -x) self.assertEqual( str(context.exception).strip(), "Bias function must be positive non-increasing") with self.assertRaises(ValueError) as context: brkga.set_bias_custom_function(lambda x: x) self.assertEqual( str(context.exception).strip(), "Bias function is not a non-increasing function") with self.assertRaises(ValueError) as context: brkga.set_bias_custom_function(lambda x: x + 1) self.assertEqual( str(context.exception).strip(), "Bias function is not a non-increasing function") with self.assertRaises(ValueError) as context: brkga.set_bias_custom_function(lambda x: math.log1p(x)) self.assertEqual( str(context.exception).strip(), "Bias function is not a non-increasing function") brkga.set_bias_custom_function(lambda x: 1.0 / math.log1p(x)) self.assertAlmostEqual(brkga._total_bias_weight, 6.554970525044798) # After 2nd call to set_bias_custom_function, brkga_params function # is always CUSTOM self.assertEqual(brkga.params.bias_type, BiasFunctionType.CUSTOM) brkga.set_bias_custom_function(lambda x: 1.0 / x) self.assertAlmostEqual(brkga._total_bias_weight, 2.9289682539682538) self.assertEqual(brkga.params.bias_type, BiasFunctionType.CUSTOM) brkga.set_bias_custom_function(lambda x: x**-2.0) self.assertAlmostEqual(brkga._total_bias_weight, 1.5497677311665408) self.assertEqual(brkga.params.bias_type, BiasFunctionType.CUSTOM) brkga.set_bias_custom_function(lambda x: x**-3.0) self.assertAlmostEqual(brkga._total_bias_weight, 1.197531985674193) self.assertEqual(brkga.params.bias_type, BiasFunctionType.CUSTOM) brkga.set_bias_custom_function(lambda x: math.exp(-x)) self.assertAlmostEqual(brkga._total_bias_weight, 0.5819502851677112) self.assertEqual(brkga.params.bias_type, BiasFunctionType.CUSTOM) # This is a constance function. brkga.set_bias_custom_function( lambda _: 1.0 / brkga.params.total_parents) self.assertAlmostEqual(brkga._total_bias_weight, 0.9999999999999999) self.assertEqual(brkga.params.bias_type, BiasFunctionType.CUSTOM) brkga.set_bias_custom_function(lambda x: 0.6325 / math.sqrt(x)) self.assertAlmostEqual(brkga._total_bias_weight, 3.175781171302612) self.assertEqual(brkga.params.bias_type, BiasFunctionType.CUSTOM) ############################################# # Constant functions test for standard BRKGA ############################################# param_values = deepcopy(self.default_param_values) param_values["params"].num_elite_parents = 1 param_values["params"].total_parents = 2 brkga = BrkgaMpIpr(**param_values) rho = 0.5 brkga.set_bias_custom_function(lambda x: rho if x == 1 else 1.0 - rho) self.assertAlmostEqual(brkga._total_bias_weight, 1.0) self.assertAlmostEqual(brkga._bias_function(1), 0.5) self.assertAlmostEqual(brkga._bias_function(2), 0.5) rho = 0.75 brkga.set_bias_custom_function(lambda x: rho if x == 1 else 1.0 - rho) self.assertAlmostEqual(brkga._total_bias_weight, 1.0) self.assertAlmostEqual(brkga._bias_function(1), 0.75) self.assertAlmostEqual(brkga._bias_function(2), 0.25) rho = 0.9 brkga.set_bias_custom_function(lambda x: rho if x == 1 else 1.0 - rho) self.assertAlmostEqual(brkga._total_bias_weight, 1.0) self.assertAlmostEqual(brkga._bias_function(1), 0.9) self.assertAlmostEqual(brkga._bias_function(2), 0.1)
def test_initialize(self): """ Tests initialize() method. """ # Double initialization. param_values = deepcopy(self.default_param_values) brkga = BrkgaMpIpr(**param_values) # 1st initialization. brkga.initialize() with self.assertRaises(RuntimeError) as context: # 2nd initialization. brkga.initialize() self.assertEqual( str(context.exception).strip(), "The algorithm is already initialized. " "Please call 'reset()' instead.") # Custom function is not defined. filename = os.path.join(CONFIG_DIR, "custom_bias_function.conf") brkga_params, _ = load_configuration(filename) param_values = deepcopy(self.default_param_values) param_values["params"] = brkga_params brkga = BrkgaMpIpr(**param_values) with self.assertRaises(ValueError) as context: brkga.initialize() self.assertEqual( str(context.exception).strip(), "The bias function is not defined. Call " "set_bias_custom_function() before call initialize().") ######################## # Test without warmstart ######################## param_values = deepcopy(self.default_param_values) param_values["sense"] = Sense.MAXIMIZE params = param_values["params"] brkga = BrkgaMpIpr(**param_values) brkga.initialize() self.assertTrue(brkga._initialized, "Flag 'brkga._initialized' is supposed to be 'True'") self.assertFalse( brkga._reset_phase, "Flag 'brkga._reset_phase' is supposed to be 'False'") self.assertEqual(len(brkga._current_populations), params.num_independent_populations) self.assertEqual(len(brkga._previous_populations), params.num_independent_populations) for i in range(params.num_independent_populations): self.assertEqual(len(brkga._current_populations[i].chromosomes), params.population_size) self.assertEqual(len(brkga._current_populations[i].fitness), params.population_size) self.assertEqual(len(brkga._previous_populations[i].chromosomes), params.population_size) self.assertEqual(len(brkga._previous_populations[i].fitness), params.population_size) self.assertEqual(brkga._current_populations[i].chromosomes, brkga._previous_populations[i].chromosomes) self.assertIsNot(brkga._current_populations[i].chromosomes, brkga._previous_populations[i].chromosomes) correct_order = True for j in range(1, brkga.params.population_size): correct_order &= \ brkga._current_populations[i].fitness[j - 1][0] >= \ brkga._current_populations[i].fitness[j][0] # end for self.assertTrue(correct_order, "incorrect chromosome order") # end for param_values = deepcopy(self.default_param_values) param_values["sense"] = Sense.MINIMIZE params = param_values["params"] brkga = BrkgaMpIpr(**param_values) brkga.initialize() for i in range(params.num_independent_populations): correct_order = True for j in range(1, brkga.params.population_size): correct_order &= \ brkga._current_populations[i].fitness[j - 1][0] <= \ brkga._current_populations[i].fitness[j][0] # end for self.assertTrue(correct_order, "incorrect chromosome order") # end for ######################## # Test with warmstart ######################## local_rng = Random(param_values["seed"]) chromosomes = [ BaseChromosome([ local_rng.random() for _ in range(param_values["chromosome_size"]) ]), BaseChromosome([ local_rng.random() for _ in range(param_values["chromosome_size"]) ]), BaseChromosome([ local_rng.random() for _ in range(param_values["chromosome_size"]) ]) ] param_values = deepcopy(self.default_param_values) param_values["sense"] = Sense.MINIMIZE params = param_values["params"] brkga = BrkgaMpIpr(**param_values) brkga.set_initial_population(chromosomes) brkga.initialize() for i in range(params.num_independent_populations): self.assertEqual(len(brkga._current_populations[i].chromosomes), params.population_size) self.assertEqual(len(brkga._current_populations[i].fitness), params.population_size) self.assertEqual(len(brkga._previous_populations[i].chromosomes), params.population_size) self.assertEqual(len(brkga._previous_populations[i].fitness), params.population_size) self.assertEqual(brkga._current_populations[i].chromosomes, brkga._previous_populations[i].chromosomes) self.assertIsNot(brkga._current_populations[i].chromosomes, brkga._previous_populations[i].chromosomes) # end for old_chr = deepcopy(chromosomes[0]) param_values["decoder"].decode(chromosomes[0], rewrite=True) self.assertNotEqual(chromosomes[0], old_chr) self.assertEqual(brkga._current_populations[0].chromosomes[0], chromosomes[0]) # Create a local chromosome and applied the decoder on it. local_rng = Random(param_values["seed"]) for _ in range(1000): local_rng.random() local_chr = BaseChromosome([ local_rng.random() for _ in range(param_values["chromosome_size"]) ]) param_values["decoder"].decode(local_chr, rewrite=True) # 4th chromosome must be the 1st generated one due to the warmstart. self.assertEqual(brkga._current_populations[0].chromosomes[3], local_chr) ######################## # Test reset phase ######################## param_values = deepcopy(self.default_param_values) params = param_values["params"] brkga = BrkgaMpIpr(**param_values) brkga.initialize() # Create a local RNG and advance it until the same state as the # internal BRKGA RNG after initialization. local_rng = Random(param_values["seed"]) skip = 1000 + params.num_independent_populations * \ params.population_size * brkga.chromosome_size for _ in range(skip): local_rng.random() self.assertEqual(brkga._rng.getstate(), local_rng.getstate()) brkga._reset_phase = True brkga.initialize() # Create a local chromosome and applied the decoder on it. local_chr = BaseChromosome([ local_rng.random() for _ in range(param_values["chromosome_size"]) ]) param_values["decoder"].decode(local_chr, rewrite=True) self.assertEqual(brkga._current_populations[0].chromosomes[0], local_chr)
def test_evolve_population0(self): """ Tests evolve_population() method. """ param_values = deepcopy(self.default_param_values) brkga_params = param_values["params"] brkga_params.num_independent_populations = 3 brkga_params.num_elite_parents = 1 brkga_params.total_parents = 2 brkga = BrkgaMpIpr(**param_values) # Not initialized with self.assertRaises(RuntimeError) as context: brkga.evolve_population(0) self.assertEqual( str(context.exception).strip(), "The algorithm hasn't been initialized. " "Call 'initialize()' before 'evolve_population()'") brkga.initialize() # Test invalid population indices. population_index = -1 with self.assertRaises(ValueError) as context: brkga.evolve_population(population_index) self.assertEqual( str(context.exception).strip(), "Population must be in [0, 2]: -1") population_index = brkga.params.num_independent_populations with self.assertRaises(ValueError) as context: brkga.evolve_population(population_index) self.assertEqual( str(context.exception).strip(), "Population must be in [0, 2]: 3") # Save previous and current populations locally current = deepcopy(brkga._current_populations) previous = deepcopy(brkga._previous_populations) ######################## # Test if algorithm swaps the populations correctly ######################## for i in range(brkga_params.num_independent_populations): brkga.evolve_population(i) # Internal current and previous generation must be different. self.assertNotEqual(brkga._current_populations[i].chromosomes, brkga._previous_populations[i].chromosomes) # The current the from this generation is equal to the previous # of the next generation. self.assertEqual(current[i].chromosomes, brkga._previous_populations[i].chromosomes) self.assertEqual(current[i].fitness, brkga._previous_populations[i].fitness) # The previous of this generation is lost. Just make sure that # the internal swap gets the new generation, not the current one. self.assertNotEqual(previous[i].chromosomes, brkga._current_populations[i].chromosomes) self.assertNotEqual(previous[i].fitness, brkga._current_populations[i].fitness) # end for print(f"Elapsed time: {time() - self.start_time :.2f}")
def test_evolve(self): """ Tests evolve() method. """ param_values = deepcopy(self.default_param_values) brkga_params = param_values["params"] brkga = BrkgaMpIpr(**param_values) # Not initialized with self.assertRaises(RuntimeError) as context: brkga.evolve() self.assertEqual( str(context.exception).strip(), "The algorithm hasn't been initialized. " "Call 'initialize()' before 'evolve()'") brkga.initialize() with self.assertRaises(ValueError) as context: brkga.evolve(-1) self.assertEqual( str(context.exception).strip(), "Number of generations must be large than one. " "Given -1") with open(os.path.join(STATE_DIR, "state5.pickle"), "rb") as hd: brkga = pickle.load(hd) with open(os.path.join(SOLUTION_DIR, "best_solution5.pickle"), "rb") as hd: results = pickle.load(hd) brkga.evolve() self.assertEqual(brkga.get_best_fitness(), results["fitness1"]) self.assertEqual(brkga.get_best_chromosome(), results["chromosome1"]) print(f"Elapsed time: {time() - self.start_time :.2f}") brkga.evolve(10) self.assertEqual(brkga.get_best_fitness(), results["fitness10"]) self.assertEqual(brkga.get_best_chromosome(), results["chromosome10"]) print(f"Elapsed time: {time() - self.start_time :.2f}") brkga.evolve(100) self.assertEqual(brkga.get_best_fitness(), results["fitness100"]) self.assertEqual(brkga.get_best_chromosome(), results["chromosome100"]) print(f"Elapsed time: {time() - self.start_time :.2f}")
def test_constructor(self): """ Tests BrkgaParams constructor. """ ######################## # Test regular/correct building. ####################### param_values = deepcopy(self.default_param_values) brkga = BrkgaMpIpr(**param_values) self.assertEqual(brkga.elite_size, 3) self.assertEqual(brkga.num_mutants, 1) brkga_params = param_values["params"] self.assertEqual(len(brkga._parents_ordered), brkga_params.total_parents) local_rng = Random(param_values["seed"]) # Same warm up that the one in the constructor. for _ in range(1000): local_rng.random() self.assertEqual(brkga._rng.getstate(), local_rng.getstate()) self.assertEqual(brkga._ChromosomeType, BaseChromosome) ######################## # Test multi-start building. ######################## param_values["evolutionary_mechanism_on"] = False param_values["params"].population_size = 10 brkga = BrkgaMpIpr(**param_values) self.assertEqual(brkga.elite_size, 1) self.assertEqual(brkga.num_mutants, 9) ######################## # Test bias functions. ######################## param_values = deepcopy(self.default_param_values) param_values["params"].bias_type = BiasFunctionType.LOGINVERSE brkga = BrkgaMpIpr(**param_values) self.assertEqual(brkga.params.bias_type, BiasFunctionType.LOGINVERSE) self.assertAlmostEqual(brkga._bias_function(1), 1.4426950408889634) self.assertAlmostEqual(brkga._bias_function(2), 0.9102392266268375) self.assertAlmostEqual(brkga._bias_function(3), 0.721347520444481) param_values["params"].bias_type = BiasFunctionType.LINEAR brkga = BrkgaMpIpr(**param_values) self.assertEqual(brkga.params.bias_type, BiasFunctionType.LINEAR) self.assertAlmostEqual(brkga._bias_function(1), 1.0) self.assertAlmostEqual(brkga._bias_function(2), 0.5) self.assertAlmostEqual(brkga._bias_function(3), 0.333333333333) param_values["params"].bias_type = BiasFunctionType.QUADRATIC brkga = BrkgaMpIpr(**param_values) self.assertEqual(brkga.params.bias_type, BiasFunctionType.QUADRATIC) self.assertAlmostEqual(brkga._bias_function(1), 1.0) self.assertAlmostEqual(brkga._bias_function(2), 0.25) self.assertAlmostEqual(brkga._bias_function(3), 0.111111111111) param_values["params"].bias_type = BiasFunctionType.CUBIC brkga = BrkgaMpIpr(**param_values) self.assertEqual(brkga.params.bias_type, BiasFunctionType.CUBIC) self.assertAlmostEqual(brkga._bias_function(1), 1.0) self.assertAlmostEqual(brkga._bias_function(2), 0.125) self.assertAlmostEqual(brkga._bias_function(3), 0.037037037037037035) param_values["params"].bias_type = BiasFunctionType.EXPONENTIAL brkga = BrkgaMpIpr(**param_values) self.assertEqual(brkga.params.bias_type, BiasFunctionType.EXPONENTIAL) self.assertAlmostEqual(brkga._bias_function(1), 0.36787944117144233) self.assertAlmostEqual(brkga._bias_function(2), 0.1353352832366127) self.assertAlmostEqual(brkga._bias_function(3), 0.049787068367863944) param_values["params"].bias_type = BiasFunctionType.CONSTANT brkga = BrkgaMpIpr(**param_values) self.assertEqual(brkga.params.bias_type, BiasFunctionType.CONSTANT) self.assertAlmostEqual(brkga._bias_function(1), 0.5) self.assertAlmostEqual(brkga._bias_function(2), 0.5) self.assertAlmostEqual(brkga._bias_function(3), 0.5) ######################## # Test exceptions. ######################## # Chromosome size param_values = deepcopy(self.default_param_values) param_values["chromosome_size"] = 0 with self.assertRaises(ValueError) as context: brkga = BrkgaMpIpr(**param_values) self.assertEqual( str(context.exception).strip(), "Chromosome size must be larger than zero: 0") param_values["chromosome_size"] = -10 with self.assertRaises(ValueError) as context: brkga = BrkgaMpIpr(**param_values) self.assertEqual( str(context.exception).strip(), "Chromosome size must be larger than zero: -10") # Population size param_values = deepcopy(self.default_param_values) param_values["params"].population_size = 0 with self.assertRaises(ValueError) as context: brkga = BrkgaMpIpr(**param_values) self.assertEqual( str(context.exception).strip(), "Population size size must be larger than zero: 0") param_values["params"].population_size = -10 with self.assertRaises(ValueError) as context: brkga = BrkgaMpIpr(**param_values) self.assertEqual( str(context.exception).strip(), "Population size size must be larger than zero: -10") # Elite size param_values = deepcopy(self.default_param_values) param_values["params"].elite_percentage = 0.0 with self.assertRaises(ValueError) as context: brkga = BrkgaMpIpr(**param_values) self.assertEqual( str(context.exception).strip(), "Elite set size less then one: 0") param_values["params"].elite_percentage = -1.0 with self.assertRaises(ValueError) as context: brkga = BrkgaMpIpr(**param_values) self.assertEqual( str(context.exception).strip(), "Elite set size less then one: -10") param_values["params"].elite_percentage = 0.3 param_values["params"].population_size = 2 with self.assertRaises(ValueError) as context: brkga = BrkgaMpIpr(**param_values) self.assertEqual( str(context.exception).strip(), "Elite set size less then one: 0") param_values["params"].elite_percentage = 1.1 param_values["params"].population_size = 10 with self.assertRaises(ValueError) as context: brkga = BrkgaMpIpr(**param_values) self.assertEqual( str(context.exception).strip(), "Elite set size (11) greater than population size (10)") # Mutant size param_values = deepcopy(self.default_param_values) param_values["params"].mutants_percentage = 0.0 brkga = BrkgaMpIpr(**param_values) self.assertEqual(brkga.num_mutants, 0) param_values["params"].mutants_percentage = -1.0 with self.assertRaises(ValueError) as context: brkga = BrkgaMpIpr(**param_values) self.assertEqual( str(context.exception).strip(), "Mutant set size less then zero: -10") param_values["params"].mutants_percentage = 1.1 with self.assertRaises(ValueError) as context: brkga = BrkgaMpIpr(**param_values) self.assertEqual( str(context.exception).strip(), "Mutant set size (11) greater than population size (10)") # Elite + Mutant size. param_values = deepcopy(self.default_param_values) param_values["params"].elite_percentage = 0.6 param_values["params"].mutants_percentage = 0.6 with self.assertRaises(ValueError) as context: brkga = BrkgaMpIpr(**param_values) self.assertEqual( str(context.exception).strip(), "Elite set size (6) + mutant set size (6) greater " "than population size (10)") # Elite parents for mating. param_values = deepcopy(self.default_param_values) param_values["params"].num_elite_parents = 0 with self.assertRaises(ValueError) as context: brkga = BrkgaMpIpr(**param_values) self.assertEqual( str(context.exception).strip(), "Number of elite parents must be at least 1: 0") param_values["params"].num_elite_parents = 1 param_values["params"].total_parents = 1 with self.assertRaises(ValueError) as context: brkga = BrkgaMpIpr(**param_values) self.assertEqual( str(context.exception).strip(), "Total parents must be at least 2: 1") param_values["params"].num_elite_parents = 2 param_values["params"].total_parents = 2 with self.assertRaises(ValueError) as context: brkga = BrkgaMpIpr(**param_values) self.assertEqual( str(context.exception).strip(), "Number of elite parents (2) is greater than or " "equal to total_parents (2)") param_values["params"].num_elite_parents = 3 param_values["params"].total_parents = 2 with self.assertRaises(ValueError) as context: brkga = BrkgaMpIpr(**param_values) self.assertEqual( str(context.exception).strip(), "Number of elite parents (3) is greater than or " "equal to total_parents (2)") brkga_params = param_values["params"] brkga_params.num_elite_parents = \ 1 + int(brkga_params.population_size * brkga_params.elite_percentage) brkga_params.total_parents = 1 + brkga_params.num_elite_parents with self.assertRaises(ValueError) as context: brkga = BrkgaMpIpr(**param_values) self.assertEqual( str(context.exception).strip(), "Number of elite parents (4) is greater than elite set (3)") # Number of independent populations. param_values = deepcopy(self.default_param_values) param_values["params"].num_independent_populations = 0 with self.assertRaises(ValueError) as context: brkga = BrkgaMpIpr(**param_values) self.assertEqual( str(context.exception).strip(), "Number of parallel populations must be larger than zero: 0") # TODO: enable the following when IPR methods be implemented. # # alpha_block_size. # param_values = deepcopy(self.default_param_values) # param_values["params"].alpha_block_size = 0 # with self.assertRaises(ValueError) as context: # brkga = BrkgaMpIpr(**param_values) # self.assertEqual(str(context.exception).strip(), # "Alpha block size must be larger than zero: 0") # # Percentage / path size. # param_values = deepcopy(self.default_param_values) # param_values["params"].pr_percentage = 0.0 # with self.assertRaises(ValueError) as context: # brkga = BrkgaMpIpr(**param_values) # self.assertEqual(str(context.exception).strip(), # "Percentage / path size must be in (0, 1]: 0.0") # param_values["params"].pr_percentage = 1.001 # with self.assertRaises(ValueError) as context: # brkga = BrkgaMpIpr(**param_values) # self.assertEqual(str(context.exception).strip(), # "Percentage / path size must be in (0, 1]: 1.001") # Invalid decoder object. param_values = deepcopy(self.default_param_values) param_values["decoder"] = None with self.assertRaises(TypeError) as context: brkga = BrkgaMpIpr(**param_values) self.assertEqual( str(context.exception).strip(), "The given decoder (<class 'NoneType'>) has no 'decode()' method") param_values["decoder"] = lambda x: sum(x) with self.assertRaises(TypeError) as context: brkga = BrkgaMpIpr(**param_values) self.assertEqual( str(context.exception).strip(), "The given decoder (<class 'function'>) has no 'decode()' method")