def generate_heatmap(ax: Axes, population_size: [int], mutation_rate: [float], ast: AST, acceptable: float, name_of_problem: str, name_of_file: str, values: [float] = None) -> None: """ Generate heatmap to compare performance in function of population size and mutation rate :param ax: An Axes :param population_size: Population sizes to use :param mutation_rate: Mutation rates to use :param ast: AST initialized :param acceptable: Acceptable difference to reach :param name_of_problem: Name of problem of heatmap generated :param name_of_file: Name of file :param values: (Optional) in case its needed :return: None, alter ax """ logging.basicConfig(level=logging.INFO) matrix = list() for size in population_size: logging.info("Population size used: {}".format(size)) generations = list() for m_rate in mutation_rate: logging.info("==> Mutation rate used: {}".format(m_rate)) ast_to_be_used = deepcopy(ast) ast_to_be_used.mutation_rate = m_rate ast_to_be_used = ast_to_be_used.generate_individual() environment = GAEngine(ast_to_be_used) if values is not None: result = environment.run_to_reach(0, acceptable, size, values=values) else: result = environment.run_to_reach(0, acceptable, size) generations.append(result.get_generations()[-1]) matrix.append(generations.copy()) matrix = np.array(matrix) mut = mutation_rate.copy() pop = population_size.copy() mut[0] = "Mutation rate:\n{}".format(mut[0]) pop[0] = "Population\nsize:\n{}".format(pop[0]) show_matrix(ax, matrix, (mut, pop), "{}: Number of iteration\n".format(name_of_problem), 20, 25, color_map="Reds") plt.savefig("../results/heatmap_{}.png".format(name_of_file))
from random import seed from genetic_algorithm import GAEngine from genetic_algorithm.individuals import WordGuesser WORD_TO_GUESS = "algorithm" SCORE = len(WORD_TO_GUESS) POPULATION_SIZE = [10, 100, 300, 500] MUTATION_RATE = list(np.arange(0, 1.05, 0.05)) seed(math.log(2)) if __name__ == '__main__': logging.basicConfig(level=logging.INFO) _, ax = plt.subplots(figsize=(12, 12)) for size in POPULATION_SIZE: logging.info("Population size used: {}".format(size)) generations = list() for m_rate in MUTATION_RATE: logging.info("==> Mutation rate used: {}".format(m_rate)) environment = GAEngine(WordGuesser(m_rate, WORD_TO_GUESS)) result = environment.run_to_reach(SCORE, 0.0, size) generations.append(result.get_generations()[-1]) ax.plot(MUTATION_RATE, generations, label="Population: {}".format(size)) ax.set_xlabel("\nMutation rate", fontsize=20) ax.set_ylabel("Generations of run\n", fontsize=20) ax.set_title("Guess word on mutation rate\n", fontsize=25) ax.legend(fontsize=20) ax.grid() plt.savefig("../results/algorithm_vs_mutation.png")
except KeyError: raise KeyError( "{} is not a valid option. Available options: " "0: word guesser, 1: sentences guesser, " "2: binary calculator, 3: traveling salesman problem".format( args.type)) individual, label, population, score = get_input(key, args.mutation_rate) logging.info("Generate engine:") environment = GAEngine(individual) logging.info("Run algorithm:") if args.equilibrium is None: result = environment.run_to_reach(score, 0.0, population, log=True, tournament_size=args.tournament_size) else: result = environment.run_to_equilibrium( population, args.equilibrium, log=True, tournament_size=args.tournament_size) _, ax = plt.subplots(figsize=(12, 12)) if key == "sentence_guesser": ax.plot(result.get_generations(), result.get_max_scores(), "-", label="{}\n(maximum score)".format(label)) ax.plot(result.get_generations(),
class GAEngineTest(TestCase): def setUp(self) -> None: """ Sets up unittest """ tester = TesterIndividual() self.ga_engine = GAEngine(tester) self.ga_engine.initialize_population(POPULATION_SIZE) def test_initialize_population(self): actual_population = self.ga_engine.population self.assertEqual(POPULATION_SIZE, len(actual_population), "Population size mismatch") self.assertEqual(POPULATION_SIZE, len(self.ga_engine), "Population size mismatch") for _ in range(RANDOM_TEST): i = randint(0, POPULATION_SIZE - 1) self.assertIsInstance(actual_population[i], TesterIndividual, "Population of unexpected class") def test_evaluate_fitness(self): self.assertLessEqual(self.ga_engine.solution_found(0.0), False, "Not always return false if not evaluated") self.ga_engine.evaluate_fitness() fitness = self.ga_engine.fitness self.assertEqual(len(fitness), POPULATION_SIZE, "Wrong number of fitness calculated") expected_score = 90 self.assertFalse(self.ga_engine.solution_found(expected_score), "Solution not found") expected_score = 70 self.assertTrue(self.ga_engine.solution_found(expected_score), "Solution found") def test_selection(self): expected_score = 50 self.ga_engine.evaluate_fitness() old_score = sum(self.ga_engine.fitness) / len(self.ga_engine) self.ga_engine.selection(expected_score) actual_population = self.ga_engine.population self.assertLess(POPULATION_SIZE, len(actual_population), "Population did not duplicate on selection") self.assertEqual(POPULATION_SIZE * 2, len(actual_population), "Population did not duplicate on selection") # Due to fitness is random: new_score = sum([x.my_fitness for x in self.ga_engine.population ]) / len(self.ga_engine) self.assertGreater(new_score, old_score, "Score did not improve") def test_reproduction(self): expected_score = 40 self.ga_engine.evaluate_fitness() self.ga_engine.selection(expected_score) self.assertLess(POPULATION_SIZE, len(self.ga_engine), "Mismatch population size") self.ga_engine.reproduction() self.assertEqual(POPULATION_SIZE, len(self.ga_engine), "Reproduction failed") self.ga_engine.evaluate_fitness() def test_add(self): new_one = GAEngine(TesterIndividual()) new_one.initialize_population(50) last_one = self.ga_engine + new_one self.assertEqual(POPULATION_SIZE + 50, len(last_one), "Add bad implemented") self.assertEqual( len(self.ga_engine) + len(new_one), len(last_one), "Add bad implemented") def test_robust_operations(self): with self.assertRaises(RuntimeError): self.ga_engine.selection() self.ga_engine.population.clear() with self.assertRaises(RuntimeError): self.ga_engine.evaluate_fitness() odd = 13 self.ga_engine.initialize_population(odd) self.ga_engine.reproduction() expected = int(odd / 2) + 1 self.assertEqual(expected, len(self.ga_engine)) self.ga_engine.population.clear() self.assertRaises(RuntimeError, self.ga_engine.run_to_equilibrium, POPULATION_SIZE, 10, use_prev=True) def test_initialize_again(self): self.assertEqual(POPULATION_SIZE, len(self.ga_engine), "Population size mismatch") self.ga_engine.initialize_population(100) self.assertEqual(100, len(self.ga_engine), "Population not over-generated") def test_next_generation(self): self.ga_engine.evaluate_fitness() self.assertEqual(1, self.ga_engine.generation, "Wrong first Generation") self.ga_engine.next_generation() self.assertEqual(100, len(self.ga_engine), "Population mismatch") self.assertEqual(2, self.ga_engine.generation, "Wrong second Generation") def test_next_generation_save(self): self.ga_engine.evaluate_fitness(register=True) self.assertEqual(1, self.ga_engine.generation, "Wrong first generation") self.ga_engine.next_generation(register=True) self.assertEqual(100, len(self.ga_engine), "Population mismatch") self.assertEqual(2, self.ga_engine.generation, "Wrong second Generation") result = self.ga_engine.result result._ready = True self.assertEqual(2, len(result), "Mismatch result size") def test_run_no_solution(self): expected = 1e10 # unreachable max_generation = 100 result = self.ga_engine.run_to_reach(expected, 0, 10, max_generation=max_generation) generations = result.get_generations()[-1] found = result.found_solution self.assertEqual(max_generation, generations, "Not stop when supposed to") self.assertFalse(found, "Found it") def test_run_solution(self): expected = 50 # reachable result = self.ga_engine.run_to_reach(expected, 0, 100) generations = result.get_generations()[-1] self.assertTrue(result.found_solution, "Solution not found") self.assertLessEqual(generations, 1000, "Run more than permitted") def test_run_equilibrium(self): self.ga_engine.the_first_one = TesterEquilibrium() result = self.ga_engine.run_to_equilibrium(100, 10) generations = result.get_generations()[-1] found = result.found_solution self.assertEqual(10, generations, "Not stop when supposed to") self.assertTrue(found, "Not found it") def test_run_fixed_generation(self): expected = 0.0 # reachable max_generation = 10 self.ga_engine.the_first_one = TesterEquilibrium() result = self.ga_engine.run_fixed_generation(100, max_generation) generations = result.get_generations()[-1] first_score = result.get_max_scores()[0] found = result.found_solution self.assertEqual(max_generation, generations, "Not stop when supposed to") self.assertTrue(found, "Not found it") self.assertGreaterEqual(EPSILON, abs(expected - first_score), "Fitness miscalculated") def setup_use_prev(self): """ Generate a previous generation to use on a new run algorithm """ self.ga_engine.evaluate_fitness() self.ga_engine.next_generation() self.ga_engine.next_generation() self.ga_engine.next_generation() self.assertEqual(4, self.ga_engine.generation, "Problem with setup prev generation") def test_run_solution_with_prev(self): self.setup_use_prev() expected = 1e10 # unreachable max_generation = 10 self.ga_engine.run_to_reach(expected, 0, 10, max_generation=max_generation, use_prev=True) self.assertNotEqual(max_generation, self.ga_engine.generation, "Not used previous generation") self.assertEqual(max_generation + 3, self.ga_engine.generation, "Wrong number of generation used") def test_run_equilibrium_with_prev(self): self.setup_use_prev() max_generation = 10 self.ga_engine.run_to_equilibrium(100, 10, max_generation=max_generation, use_prev=True) self.assertNotEqual(max_generation, self.ga_engine.generation, "Not used previous generation") self.assertEqual(max_generation + 3, self.ga_engine.generation, "Wrong number of generation used") def test_run_fixed_generation_with_prev(self): self.setup_use_prev() max_generation = 10 self.ga_engine.run_fixed_generation(100, max_generation, use_prev=True) self.assertNotEqual(max_generation, self.ga_engine.generation, "Not used previous generation") self.assertEqual(max_generation + 3, self.ga_engine.generation, "Wrong number of generation used")
required=True, help="What kind of game:\n" "Available:\tunbound,\tyes-or-no") args = parser.parse_args() try: ast = PROBLEMS[args.what_kind] population_size = POPULATION_SIZE[args.what_kind] acceptable = ACCEPTABLE[args.what_kind] except KeyError: raise KeyError( "{} problem is not an option, available: unbound and yes-or-no". format(args.what_knapsack)) environment = GAEngine(ast) result = environment.run_to_reach(0, acceptable, population_size, log=True) _, ax = plt.subplots(figsize=(12, 12)) title = "yes-or-no" if args.what_kind == "unbound": title = "Unbound" ax.set_title("Des Chiffres Et Des Lettres ({})\n".format(title), fontsize=25) ax.set_xlabel("\nGeneration", fontsize=20) ax.set_ylabel("Score\n", fontsize=20) ax.tick_params(labelsize=20) ax.grid() ax.plot(result.get_generations(), result.get_max_scores(),