From 10bfdd3fde579897f03b60a660b199a96f7973e5 Mon Sep 17 00:00:00 2001 From: Lukian Date: Tue, 17 Dec 2024 10:55:50 +0100 Subject: [PATCH] Saataa andagii ! --- lib/ultra_mastermind_pp_imp.py | 70 ++++++++++++++++++++-------------- main.py | 2 +- requirements.txt | 11 ++++++ tests.py | 41 ++++++++++++++++---- 4 files changed, 87 insertions(+), 37 deletions(-) diff --git a/lib/ultra_mastermind_pp_imp.py b/lib/ultra_mastermind_pp_imp.py index c03a35e..96c25e0 100644 --- a/lib/ultra_mastermind_pp_imp.py +++ b/lib/ultra_mastermind_pp_imp.py @@ -21,8 +21,7 @@ def max_i(array: list[int]) -> int: max_i = i return max_i - -def new_population(pm, ng, n, ts, tm, alpha, fm): # -> set(list(set(str)), str, int, int, int, float, float, float, int) +def new_population(pm, ng, n, ts, tm, alpha, fm): """ fonction qui renvoie une nouvelle population """ @@ -43,7 +42,7 @@ def new_population(pm, ng, n, ts, tm, alpha, fm): # -> set(list(set(str)), str, return population -def new_individual(): # -> set(str) +def new_individual(): """ fonction qui renvoie un nouvel individu """ @@ -66,7 +65,8 @@ def fitness1(individual, pm) -> int: """ sum = 0 for i in range(len(individual["chromozome"])): - sum += abs(ord(individual["chromozome"][i]) - ord(pm[i])) + if i < len(pm) and i < len(individual["chromozome"]): + sum += abs(ord(individual["chromozome"][i]) - ord(pm[i])) return -sum def fitness2(individual, pm, alpha) -> int: @@ -76,7 +76,7 @@ def fitness2(individual, pm, alpha) -> int: match = 0 missed_placed = 0 for i in range(len(individual["chromozome"])): - if i > len(pm): + if i >= len(pm): missed_placed += len(individual["chromozome"]) - len(pm) break elif individual["chromozome"][i] == pm[i]: @@ -104,13 +104,17 @@ def get_fitness(population, individual) -> int: case _: return fitness1(individual, population["pm"]) +def get_fitness_list(population): + fitness_list = [] + for individual in population["individuals"]: + fitness_list.append(get_fitness(population, individual)) + return fitness_list + def get_best(population): """ Methode qui renvoie le meilleur individu de la population """ - fitness_list = [] - for individual in population["individuals"]: - fitness_list.append(get_fitness(population, individual)) + fitness_list = get_fitness_list(population) return population["individuals"][max_i(fitness_list)] def print_best(population) -> None: @@ -119,49 +123,57 @@ def print_best(population) -> None: """ print(get_best(population)["chromozome"]) -def mutate(individual) -> None: - """ - Methode qui change un des caractères du chromozome - """ - new = list(individual["chromozome"]) - if random.randint(1, 2) == 1: new.insert(random.randint(0, len(new) - 1), chr(random.randint(0, 255))) - else : new[random.randint(0, len(new) - 1)] = chr(random.randint(0, 255)) - individual["chromozome"] = "".join(new) - def select(population) -> None: """ Methode qui sélectionne les meilleurs individus """ - fitness_list = [] - for individual in population["individuals"]: - fitness_list.append(get_fitness(population, individual)) - + fitness_list = get_fitness_list(population) for i in range(int((1 - population["ts"]) * population["n"])): least = min_i(fitness_list) fitness_list.pop(least) population["individuals"].pop(least) +def get_two_random_individuals(population): + i = random.randint(0, len(population["individuals"]) - 1) + j = random.randint(0, len(population["individuals"]) - 1) + while i == j: + j = random.randint(0, len(population["individuals"]) - 1) + return (population["individuals"][i], population['individuals'][j]) + def reproduct(population) -> None: """ Methode qui reproduit les individus entre eux jusqu'à obtenir une population de taille N """ new = [] while len(population["individuals"]) + len(new) != population["n"]: - i = random.randint(0, len(population["individuals"]) - 1) - j = random.randint(0, len(population["individuals"]) - 1) - while i == j: - j = random.randint(0, len(population["individuals"]) - 1) - indivi_1 = population["individuals"][i] - indivi_2 = population['individuals'][j] + indivi_1, indivi_2 = get_two_random_individuals(population) + avg = (len(indivi_1) + len(indivi_2)) // 2 cut = random.randint(avg // 3, 2 * avg // 3) - while cut > len(indivi_1) or cut > len(indivi_2): cut = random.randint(avg // 3, 2 * avg // 3) - new_chromozome = indivi_1["chromozome"][:cut] + indivi_2["chromozome"][-cut:] + while cut > len(indivi_1) or cut > len(indivi_2): + cut = random.randint(avg // 3, 2 * avg // 3) + + new_chromozome = indivi_1["chromozome"][:cut] + indivi_2["chromozome"][cut:] child = new_individual() child["chromozome"] = new_chromozome new.append(child) + population["individuals"] += new +def mutate(individual) -> None: + """ + Methode qui change un des caractères du chromozome + """ + new = list(individual["chromozome"]) + dice = random.randint(1,3) + if dice == 1 and len(new) < 30: + new.insert(random.randint(0, len(new) - 1), chr(random.randint(0, 255))) + elif dice == 2 and len(new) > 4: + new.pop(random.randint(0, len(new) - 1)) + else : + new[random.randint(0, len(new) - 1)] = chr(random.randint(0, 255)) + individual["chromozome"] = "".join(new) + def mutate_pop(population) -> None: """ Methode qui mute une partie de la population selon le taut de mutation diff --git a/main.py b/main.py index 2f76300..4d6d75c 100644 --- a/main.py +++ b/main.py @@ -8,7 +8,7 @@ import lib.ultra_mastermind_pp_imp as libppimp # constants PM = "" NG = 500 -N = 200 +N = 300 TS = 0.5 TM = 0.25 ALPHA = 0.5 diff --git a/requirements.txt b/requirements.txt index 42f9564..a8a1a86 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,13 @@ +contourpy==1.3.1 +cycler==0.12.1 +fonttools==4.55.0 +kiwisolver==1.4.7 Levenshtein==0.26.1 +matplotlib==3.9.2 +numpy==2.1.3 +packaging==24.2 +pillow==11.0.0 +pyparsing==3.2.0 +python-dateutil==2.9.0.post0 RapidFuzz==3.10.1 +six==1.16.0 diff --git a/tests.py b/tests.py index 4eec2f5..5d3d0a7 100644 --- a/tests.py +++ b/tests.py @@ -5,6 +5,7 @@ import matplotlib.pyplot as plt # project libs importations import lib.ultra_mastermind_obj as libobj import lib.ultra_mastermind_imp as libimp +import lib.ultra_mastermind_pp_imp as libppimp # Variation du nombre de générations PM = "Hello, world!" @@ -13,20 +14,46 @@ N = 400 TS = 0.5 TM = 0.25 ALPHA = 0.5 -FITNESS_METHOD = 1 +FITNESS_METHOD = 3 fitness_ng = [] all_ng = [] -for i in range(1, 21): - NG = i * 100 +for i in range(1, 11): + NG = i * 200 all_ng.append(NG) - pop = libimp.new_population(PM, NG, N, TS, TM, ALPHA, FITNESS_METHOD) - libimp.run(pop) - fitness_ng.append(libimp.get_fitness(pop, libimp.get_best(pop))) + pop = libppimp.new_population(PM, NG, N, TS, TM, ALPHA, FITNESS_METHOD) + libppimp.run(pop) + fitness_ng.append(libppimp.get_fitness(pop, libppimp.get_best(pop))) plt.plot(all_ng, fitness_ng) -plt.title("Fitness du meilleur individu en fonciton du nombre de générations") +plt.title("Fitness du meilleur individu en fonction du nombre de générations") plt.xlabel("Nombre de générations") plt.ylabel("Fitness du meilleur individu") plt.show() + +# Variation du nombre de générations +PM = "Hello, world!" +NG = 500 +# N = 400 +TS = 0.5 +TM = 0.25 +ALPHA = 0.5 +FITNESS_METHOD = 3 + +fitness_n = [] +all_n = [] + +for i in range(1, 11): + N = i * 100 + all_n.append(N) + pop = libppimp.new_population(PM, NG, N, TS, TM, ALPHA, FITNESS_METHOD) + libppimp.run(pop) + fitness_n.append(libppimp.get_fitness(pop, libppimp.get_best(pop))) + +plt.plot(all_n, fitness_n) +plt.title("Fitness du meilleur individu en fonction de la taille de population") +plt.xlabel("Taille de population") +plt.ylabel("Fitness du meilleur individu") +plt.show() +