Saataa andagii !
This commit is contained in:
parent
d99a556d3d
commit
757ea77cc5
8 changed files with 549 additions and 500 deletions
|
@ -5,6 +5,7 @@
|
||||||
### Linux
|
### Linux
|
||||||
|
|
||||||
- `git clone https://git.leizour.fr/lucien/ultra-mastermind-implementation`
|
- `git clone https://git.leizour.fr/lucien/ultra-mastermind-implementation`
|
||||||
|
- `cd ultra-mastermind-implementation`
|
||||||
- `python -m venv .venv`
|
- `python -m venv .venv`
|
||||||
- `source .venv/bin/activate`
|
- `source .venv/bin/activate`
|
||||||
- `pip install -r requirements.txt`
|
- `pip install -r requirements.txt`
|
||||||
|
@ -20,8 +21,9 @@
|
||||||
#### Second method
|
#### Second method
|
||||||
|
|
||||||
- `git clone https://git.leizour.fr/lucien/ultra-mastermind-implementation`
|
- `git clone https://git.leizour.fr/lucien/ultra-mastermind-implementation`
|
||||||
|
- `cd ultra-mastermind-implementation`
|
||||||
- `python -m venv .venv`
|
- `python -m venv .venv`
|
||||||
- `./.venv/bin/activate`
|
- `.venv/bin/activate`
|
||||||
- `pip install -r requirements.txt`
|
- `pip install -r requirements.txt`
|
||||||
- `python main.py`
|
- `python main.py`
|
||||||
|
|
||||||
|
|
103
analyse.py
Normal file
103
analyse.py
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
# fichier de tests du projet
|
||||||
|
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import random
|
||||||
|
|
||||||
|
# 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
|
||||||
|
|
||||||
|
PM = "Hello, world!"
|
||||||
|
NG = 4000
|
||||||
|
N = 400
|
||||||
|
TS = 0.7
|
||||||
|
TM = 0.25
|
||||||
|
ALPHA = 0.5
|
||||||
|
FITNESS_METHOD = 3
|
||||||
|
|
||||||
|
# Variation de la taille de la phrase
|
||||||
|
length_ng = []
|
||||||
|
length = []
|
||||||
|
|
||||||
|
for i in range(5, 26, 3):
|
||||||
|
print(f"Step {i}:")
|
||||||
|
length.append(i)
|
||||||
|
vals = []
|
||||||
|
for j in range(5):
|
||||||
|
print(f" Part {j}")
|
||||||
|
PM = "".join([chr(random.randint(0, 255)) for _ in range(i)])
|
||||||
|
pop = libppimp.new_population(PM, NG, N, TS, TM, ALPHA, FITNESS_METHOD)
|
||||||
|
ng = libppimp.run(pop)
|
||||||
|
vals.append(ng)
|
||||||
|
length_ng.append(sum(vals) / len(vals))
|
||||||
|
|
||||||
|
plt.plot(length, length_ng)
|
||||||
|
plt.title("Nombre de générations nécéssaires en fonction de la taille de la phrase.")
|
||||||
|
plt.xlabel("Taille de la phrase")
|
||||||
|
plt.ylabel("Nombre de générations")
|
||||||
|
plt.show()
|
||||||
|
|
||||||
|
# Variation de la taille de la population
|
||||||
|
n_ng = []
|
||||||
|
n = []
|
||||||
|
|
||||||
|
for i in range(50, 1000, 100):
|
||||||
|
print(f"Step {i}:")
|
||||||
|
n.append(i)
|
||||||
|
vals = []
|
||||||
|
for j in range(5):
|
||||||
|
print(f" Part {j}")
|
||||||
|
pop = libppimp.new_population(PM, NG, i, TS, TM, ALPHA, FITNESS_METHOD)
|
||||||
|
ng = libppimp.run(pop)
|
||||||
|
vals.append(ng)
|
||||||
|
n_ng.append(sum(vals) / len(vals))
|
||||||
|
|
||||||
|
plt.plot(n, n_ng)
|
||||||
|
plt.title("Nombre de générations nécéssaires en fonction de la taille de la population.")
|
||||||
|
plt.xlabel("Taille de la population")
|
||||||
|
plt.ylabel("Nombre de générations")
|
||||||
|
plt.show()
|
||||||
|
|
||||||
|
# Variation du taut de sélection
|
||||||
|
ts_ng = []
|
||||||
|
ts = []
|
||||||
|
|
||||||
|
for i in range(1, 9, 1):
|
||||||
|
print(f"Step {i / 10}:")
|
||||||
|
ts.append(i / 10)
|
||||||
|
vals = []
|
||||||
|
for j in range(5):
|
||||||
|
print(f" Part {j}")
|
||||||
|
pop = libppimp.new_population(PM, NG, N, i / 10, TM, ALPHA, FITNESS_METHOD)
|
||||||
|
ng = libppimp.run(pop)
|
||||||
|
vals.append(ng)
|
||||||
|
ts_ng.append(sum(vals) / len(vals))
|
||||||
|
|
||||||
|
plt.plot(ts, ts_ng)
|
||||||
|
plt.title("Nombre de générations nécéssaires en fonction du taut de sélection.")
|
||||||
|
plt.xlabel("Taut de sélection")
|
||||||
|
plt.ylabel("Nombre de générations")
|
||||||
|
plt.show()
|
||||||
|
|
||||||
|
# Variation du taut de mutation
|
||||||
|
tm_ng = []
|
||||||
|
tm = []
|
||||||
|
|
||||||
|
for i in range(10, 40, 5):
|
||||||
|
print(f"Step {i / 100}:")
|
||||||
|
tm.append(i / 100)
|
||||||
|
vals = []
|
||||||
|
for j in range(5):
|
||||||
|
print(f" Part {j}")
|
||||||
|
pop = libppimp.new_population(PM, NG, N, TS, i / 100, ALPHA, FITNESS_METHOD)
|
||||||
|
ng = libppimp.run(pop)
|
||||||
|
vals.append(ng)
|
||||||
|
tm_ng.append(sum(vals) / len(vals))
|
||||||
|
|
||||||
|
plt.plot(tm, tm_ng)
|
||||||
|
plt.title("Nombre de générations nécéssaires en fonction du taut de mutation.")
|
||||||
|
plt.xlabel("Taut de mutation")
|
||||||
|
plt.ylabel("Nombre de générations")
|
||||||
|
plt.show()
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 44 KiB |
|
@ -4,174 +4,174 @@ import random
|
||||||
import Levenshtein
|
import Levenshtein
|
||||||
|
|
||||||
def min_i(array: list[int]) -> int:
|
def min_i(array: list[int]) -> int:
|
||||||
min_val = array[0]
|
min_val = array[0]
|
||||||
min_i = 0
|
min_i = 0
|
||||||
for i in range(len(array)):
|
for i in range(len(array)):
|
||||||
if array[i] < min_val:
|
if array[i] < min_val:
|
||||||
min_val = array[i]
|
min_val = array[i]
|
||||||
min_i = i
|
min_i = i
|
||||||
return min_i
|
return min_i
|
||||||
|
|
||||||
def max_i(array: list[int]) -> int:
|
def max_i(array: list[int]) -> int:
|
||||||
max_val = array[0]
|
max_val = array[0]
|
||||||
max_i = 0
|
max_i = 0
|
||||||
for i in range(len(array)):
|
for i in range(len(array)):
|
||||||
if array[i] > max_val:
|
if array[i] > max_val:
|
||||||
max_val = array[i]
|
max_val = array[i]
|
||||||
max_i = i
|
max_i = i
|
||||||
return max_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): # -> set(list(set(str)), str, int, int, int, float, float, float, int)
|
||||||
"""
|
"""
|
||||||
fonction qui renvoie une nouvelle population
|
fonction qui renvoie une nouvelle population
|
||||||
"""
|
"""
|
||||||
population = {
|
population = {
|
||||||
"individuals": [new_individual() for i in range(n)],
|
"individuals": [new_individual() for i in range(n)],
|
||||||
"pm": pm,
|
"pm": pm,
|
||||||
"ng": ng,
|
"ng": ng,
|
||||||
"l": len(pm),
|
"l": len(pm),
|
||||||
"n": n,
|
"n": n,
|
||||||
"ts": ts,
|
"ts": ts,
|
||||||
"tm": tm,
|
"tm": tm,
|
||||||
"alpha": alpha,
|
"alpha": alpha,
|
||||||
"fm": fm
|
"fm": fm
|
||||||
}
|
}
|
||||||
|
|
||||||
for individual in population["individuals"]:
|
for individual in population["individuals"]:
|
||||||
randomize(individual, len(pm))
|
randomize(individual, len(pm))
|
||||||
|
|
||||||
return population
|
return population
|
||||||
|
|
||||||
def new_individual(): # -> set(str)
|
def new_individual(): # -> set(str)
|
||||||
"""
|
"""
|
||||||
fonction qui renvoie un nouvel individu
|
fonction qui renvoie un nouvel individu
|
||||||
"""
|
"""
|
||||||
return {
|
return {
|
||||||
"chromozome": ""
|
"chromozome": ""
|
||||||
}
|
}
|
||||||
|
|
||||||
def randomize(individual, l) -> str:
|
def randomize(individual, l) -> str:
|
||||||
"""
|
"""
|
||||||
Methode qui change la valeur d'un chromozome pour une valeur aléatoire
|
Methode qui change la valeur d'un chromozome pour une valeur aléatoire
|
||||||
"""
|
"""
|
||||||
new = ""
|
new = ""
|
||||||
for i in range(l):
|
for i in range(l):
|
||||||
new += chr(random.randint(0, 255))
|
new += chr(random.randint(0, 255))
|
||||||
individual["chromozome"] = new
|
individual["chromozome"] = new
|
||||||
|
|
||||||
def fitness1(individual, pm) -> int:
|
def fitness1(individual, pm) -> int:
|
||||||
"""
|
"""
|
||||||
Première methode de fitness, fait la somme des différences entre les codages des caractères des deux chaînes.
|
Première methode de fitness, fait la somme des différences entre les codages des caractères des deux chaînes.
|
||||||
"""
|
"""
|
||||||
sum = 0
|
sum = 0
|
||||||
for i in range(len(individual["chromozome"])):
|
for i in range(len(individual["chromozome"])):
|
||||||
sum += abs(ord(individual["chromozome"][i]) - ord(pm[i]))
|
sum += abs(ord(individual["chromozome"][i]) - ord(pm[i]))
|
||||||
return -sum
|
return -sum
|
||||||
|
|
||||||
def fitness2(individual, pm, alpha) -> int:
|
def fitness2(individual, pm, alpha) -> int:
|
||||||
"""
|
"""
|
||||||
Deuxième methode de fitness qui compte les caractères bien placés et mal placés et qui renvoie un int pondéré par alpha
|
Deuxième methode de fitness qui compte les caractères bien placés et mal placés et qui renvoie un int pondéré par alpha
|
||||||
"""
|
"""
|
||||||
match = 0
|
match = 0
|
||||||
missed_placed = 0
|
missed_placed = 0
|
||||||
for i in range(len(individual["chromozome"])):
|
for i in range(len(individual["chromozome"])):
|
||||||
if individual["chromozome"][i] == pm[i]:
|
if individual["chromozome"][i] == pm[i]:
|
||||||
match += 1
|
match += 1
|
||||||
else:
|
else:
|
||||||
missed_placed += 1
|
missed_placed += 1
|
||||||
return match + alpha * missed_placed
|
return match + alpha * missed_placed
|
||||||
|
|
||||||
def fitness3(individual, pm) -> int:
|
def fitness3(individual, pm) -> int:
|
||||||
"""
|
"""
|
||||||
Troisième methode de fitness qui utilise la distance de Levenshtein
|
Troisième methode de fitness qui utilise la distance de Levenshtein
|
||||||
"""
|
"""
|
||||||
return -Levenshtein.distance(individual["chromozome"], pm)
|
return -Levenshtein.distance(individual["chromozome"], pm)
|
||||||
|
|
||||||
def get_fitness(population, individual) -> int:
|
def get_fitness(population, individual) -> int:
|
||||||
match population["fm"]:
|
match population["fm"]:
|
||||||
case 1:
|
case 1:
|
||||||
return fitness1(individual, population["pm"])
|
return fitness1(individual, population["pm"])
|
||||||
case 2:
|
case 2:
|
||||||
return fitness2(individual, population["pm"], population["alpha"])
|
return fitness2(individual, population["pm"], population["alpha"])
|
||||||
case 3:
|
case 3:
|
||||||
return fitness3(individual, population["pm"])
|
return fitness3(individual, population["pm"])
|
||||||
case _:
|
case _:
|
||||||
return fitness1(individual, population["pm"])
|
return fitness1(individual, population["pm"])
|
||||||
|
|
||||||
def get_best(population):
|
def get_best(population):
|
||||||
"""
|
"""
|
||||||
Methode qui renvoie le meilleur individu de la population
|
Methode qui renvoie le meilleur individu de la population
|
||||||
"""
|
"""
|
||||||
fitness_list = []
|
fitness_list = []
|
||||||
for individual in population["individuals"]:
|
for individual in population["individuals"]:
|
||||||
fitness_list.append(get_fitness(population, individual))
|
fitness_list.append(get_fitness(population, individual))
|
||||||
return population["individuals"][max_i(fitness_list)]
|
return population["individuals"][max_i(fitness_list)]
|
||||||
|
|
||||||
def print_best(population) -> None:
|
def print_best(population) -> None:
|
||||||
"""
|
"""
|
||||||
Methode qui affiche le meilleur individu de la population
|
Methode qui affiche le meilleur individu de la population
|
||||||
"""
|
"""
|
||||||
print(get_best(population)["chromozome"])
|
print(get_best(population)["chromozome"])
|
||||||
|
|
||||||
def mutate(individual) -> None:
|
def mutate(individual) -> None:
|
||||||
"""
|
"""
|
||||||
Methode qui change un des caractères du chromozome
|
Methode qui change un des caractères du chromozome
|
||||||
"""
|
"""
|
||||||
new = list(individual["chromozome"])
|
new = list(individual["chromozome"])
|
||||||
new[random.randint(0, len(new) - 1)] = chr(random.randint(0, 255))
|
new[random.randint(0, len(new) - 1)] = chr(random.randint(0, 255))
|
||||||
individual["chromozome"] = "".join(new)
|
individual["chromozome"] = "".join(new)
|
||||||
|
|
||||||
def select(population) -> None:
|
def select(population) -> None:
|
||||||
"""
|
"""
|
||||||
Methode qui sélectionne les meilleurs individus
|
Methode qui sélectionne les meilleurs individus
|
||||||
"""
|
"""
|
||||||
fitness_list = []
|
fitness_list = []
|
||||||
for individual in population["individuals"]:
|
for individual in population["individuals"]:
|
||||||
fitness_list.append(get_fitness(population, individual))
|
fitness_list.append(get_fitness(population, individual))
|
||||||
|
|
||||||
for i in range(int((1 - population["ts"]) * population["n"])):
|
for i in range(int((1 - population["ts"]) * population["n"])):
|
||||||
least = min_i(fitness_list)
|
least = min_i(fitness_list)
|
||||||
fitness_list.pop(least)
|
fitness_list.pop(least)
|
||||||
population["individuals"].pop(least)
|
population["individuals"].pop(least)
|
||||||
|
|
||||||
def reproduct(population) -> None:
|
def reproduct(population) -> None:
|
||||||
"""
|
"""
|
||||||
Methode qui reproduit les individus entre eux jusqu'à obtenir une population de taille N
|
Methode qui reproduit les individus entre eux jusqu'à obtenir une population de taille N
|
||||||
"""
|
"""
|
||||||
new = []
|
new = []
|
||||||
while len(population["individuals"]) + len(new) != population["n"]:
|
while len(population["individuals"]) + len(new) != population["n"]:
|
||||||
cut = random.randint(int(population["l"] / 3), int(2 * population["l"] / 3))
|
cut = random.randint(int(population["l"] / 3), int(2 * population["l"] / 3))
|
||||||
i = random.randint(0, len(population["individuals"]) - 1)
|
i = random.randint(0, len(population["individuals"]) - 1)
|
||||||
j = random.randint(0, len(population["individuals"]) - 1)
|
j = random.randint(0, len(population["individuals"]) - 1)
|
||||||
while i == j:
|
while i == j:
|
||||||
j = random.randint(0, len(population["individuals"]) - 1)
|
j = random.randint(0, len(population["individuals"]) - 1)
|
||||||
indivi_1 = population["individuals"][i]
|
indivi_1 = population["individuals"][i]
|
||||||
indivi_2 = population['individuals'][j]
|
indivi_2 = population['individuals'][j]
|
||||||
new_chromozome = indivi_1["chromozome"][:cut] + indivi_2["chromozome"][cut:]
|
new_chromozome = indivi_1["chromozome"][:cut] + indivi_2["chromozome"][cut:]
|
||||||
child = new_individual()
|
child = new_individual()
|
||||||
child["chromozome"] = new_chromozome
|
child["chromozome"] = new_chromozome
|
||||||
new.append(child)
|
new.append(child)
|
||||||
population["individuals"] += new
|
population["individuals"] += new
|
||||||
|
|
||||||
def mutate_pop(population) -> None:
|
def mutate_pop(population) -> None:
|
||||||
"""
|
"""
|
||||||
Methode qui mute une partie de la population selon le taut de mutation
|
Methode qui mute une partie de la population selon le taut de mutation
|
||||||
"""
|
"""
|
||||||
mutated = []
|
mutated = []
|
||||||
for i in range(int(population["tm"] * population["n"])):
|
for i in range(int(population["tm"] * population["n"])):
|
||||||
to_mutate = random.randint(0, population["n"] - 1)
|
to_mutate = random.randint(0, population["n"] - 1)
|
||||||
while to_mutate in mutated:
|
while to_mutate in mutated:
|
||||||
to_mutate = random.randint(0, population["n"] - 1)
|
to_mutate = random.randint(0, population["n"] - 1)
|
||||||
mutate(population["individuals"][to_mutate])
|
mutate(population["individuals"][to_mutate])
|
||||||
mutated.append(to_mutate)
|
mutated.append(to_mutate)
|
||||||
|
|
||||||
def run(population) -> None:
|
def run(population) -> None:
|
||||||
"""
|
"""
|
||||||
Boucle principale
|
Boucle principale
|
||||||
"""
|
"""
|
||||||
for i in range(population["ng"]):
|
for i in range(population["ng"]):
|
||||||
select(population)
|
select(population)
|
||||||
reproduct(population)
|
reproduct(population)
|
||||||
mutate_pop(population)
|
mutate_pop(population)
|
||||||
print_best(population)
|
print_best(population)
|
||||||
|
|
|
@ -4,170 +4,170 @@ import random
|
||||||
import Levenshtein
|
import Levenshtein
|
||||||
|
|
||||||
def min_i(array: list[int]) -> int:
|
def min_i(array: list[int]) -> int:
|
||||||
min_val = array[0]
|
min_val = array[0]
|
||||||
min_i = 0
|
min_i = 0
|
||||||
for i in range(len(array)):
|
for i in range(len(array)):
|
||||||
if array[i] < min_val:
|
if array[i] < min_val:
|
||||||
min_val = array[i]
|
min_val = array[i]
|
||||||
min_i = i
|
min_i = i
|
||||||
return min_i
|
return min_i
|
||||||
|
|
||||||
def max_i(array: list[int]) -> int:
|
def max_i(array: list[int]) -> int:
|
||||||
max_val = array[0]
|
max_val = array[0]
|
||||||
max_i = 0
|
max_i = 0
|
||||||
for i in range(len(array)):
|
for i in range(len(array)):
|
||||||
if array[i] > max_val:
|
if array[i] > max_val:
|
||||||
max_val = array[i]
|
max_val = array[i]
|
||||||
max_i = i
|
max_i = i
|
||||||
return max_i
|
return max_i
|
||||||
|
|
||||||
class Population:
|
class Population:
|
||||||
"""
|
"""
|
||||||
Classe qui représente notre population d'individuts
|
Classe qui représente notre population d'individuts
|
||||||
"""
|
"""
|
||||||
def __init__(self, pm, ng, n, ts, tm, alpha, fm):
|
def __init__(self, pm, ng, n, ts, tm, alpha, fm):
|
||||||
self.individuals = [Individual() for _ in range(n)]
|
self.individuals = [Individual() for _ in range(n)]
|
||||||
for individual in self.individuals:
|
for individual in self.individuals:
|
||||||
individual.randomize(len(pm))
|
individual.randomize(len(pm))
|
||||||
self.pm = pm
|
self.pm = pm
|
||||||
self.ng = ng
|
self.ng = ng
|
||||||
self.l = len(pm)
|
self.l = len(pm)
|
||||||
self.n = n
|
self.n = n
|
||||||
self.ts = ts
|
self.ts = ts
|
||||||
self.tm = tm
|
self.tm = tm
|
||||||
self.alpha = alpha
|
self.alpha = alpha
|
||||||
self.fitness_method = fm
|
self.fitness_method = fm
|
||||||
|
|
||||||
def select(self) -> None:
|
def select(self) -> None:
|
||||||
"""
|
"""
|
||||||
Methode qui sélectionne les meilleurs individus
|
Methode qui sélectionne les meilleurs individus
|
||||||
"""
|
"""
|
||||||
fitness_list = []
|
fitness_list = []
|
||||||
for individual in self.individuals:
|
for individual in self.individuals:
|
||||||
match self.fitness_method:
|
match self.fitness_method:
|
||||||
case 1:
|
case 1:
|
||||||
fitness_list.append(individual.fitness1(self.pm))
|
fitness_list.append(individual.fitness1(self.pm))
|
||||||
case 2:
|
case 2:
|
||||||
fitness_list.append(individual.fitness2(self.pm, self.alpha))
|
fitness_list.append(individual.fitness2(self.pm, self.alpha))
|
||||||
case 3:
|
case 3:
|
||||||
fitness_list.append(individual.fitness3(self.pm))
|
fitness_list.append(individual.fitness3(self.pm))
|
||||||
case _:
|
case _:
|
||||||
fitness_list.append(individual.fitness1(self.pm))
|
fitness_list.append(individual.fitness1(self.pm))
|
||||||
for i in range(int((1 - self.ts) * self.n)):
|
for i in range(int((1 - self.ts) * self.n)):
|
||||||
least = min_i(fitness_list)
|
least = min_i(fitness_list)
|
||||||
fitness_list.pop(least)
|
fitness_list.pop(least)
|
||||||
self.individuals.pop(least)
|
self.individuals.pop(least)
|
||||||
|
|
||||||
def reproduct(self) -> None:
|
def reproduct(self) -> None:
|
||||||
"""
|
"""
|
||||||
Methode qui reproduit les individus entre eux jusqu'à obtenir une population de taille N
|
Methode qui reproduit les individus entre eux jusqu'à obtenir une population de taille N
|
||||||
"""
|
"""
|
||||||
new = []
|
new = []
|
||||||
while len(self.individuals) + len(new) != self.n:
|
while len(self.individuals) + len(new) != self.n:
|
||||||
cut = random.randint(int(self.l / 3), int(2 * self.l / 3))
|
cut = random.randint(int(self.l / 3), int(2 * self.l / 3))
|
||||||
indivi_1 = self.individuals[random.randint(0, len(self.individuals) - 1)]
|
indivi_1 = self.individuals[random.randint(0, len(self.individuals) - 1)]
|
||||||
indivi_2 = self.individuals[random.randint(0, len(self.individuals) - 1)]
|
indivi_2 = self.individuals[random.randint(0, len(self.individuals) - 1)]
|
||||||
while indivi_1 == indivi_2:
|
while indivi_1 == indivi_2:
|
||||||
indivi_2 = self.individuals[random.randint(0, len(self.individuals) - 1)]
|
indivi_2 = self.individuals[random.randint(0, len(self.individuals) - 1)]
|
||||||
new_chromozome = indivi_1.getChromozome()[:cut] + indivi_2.getChromozome()[cut:]
|
new_chromozome = indivi_1.getChromozome()[:cut] + indivi_2.getChromozome()[cut:]
|
||||||
child = Individual()
|
child = Individual()
|
||||||
child.setChromozome(new_chromozome)
|
child.setChromozome(new_chromozome)
|
||||||
new.append(child)
|
new.append(child)
|
||||||
self.individuals += new
|
self.individuals += new
|
||||||
|
|
||||||
def mutate(self) -> None:
|
def mutate(self) -> None:
|
||||||
"""
|
"""
|
||||||
Methode qui mute une partie de la population selon le taut de mutation
|
Methode qui mute une partie de la population selon le taut de mutation
|
||||||
"""
|
"""
|
||||||
mutated = []
|
mutated = []
|
||||||
for i in range(int(self.tm * self.n)):
|
for i in range(int(self.tm * self.n)):
|
||||||
to_mutate = random.randint(0, self.n - 1)
|
to_mutate = random.randint(0, self.n - 1)
|
||||||
while to_mutate in mutated:
|
while to_mutate in mutated:
|
||||||
to_mutate = random.randint(0, self.n - 1)
|
to_mutate = random.randint(0, self.n - 1)
|
||||||
self.individuals[to_mutate].mutate()
|
self.individuals[to_mutate].mutate()
|
||||||
mutated.append(to_mutate)
|
mutated.append(to_mutate)
|
||||||
|
|
||||||
def print_best(self) -> None:
|
def print_best(self) -> None:
|
||||||
"""
|
"""
|
||||||
Methode qui affiche le meilleur individu de la population
|
Methode qui affiche le meilleur individu de la population
|
||||||
"""
|
"""
|
||||||
fitness_list = []
|
fitness_list = []
|
||||||
for individual in self.individuals:
|
for individual in self.individuals:
|
||||||
match self.fitness_method:
|
match self.fitness_method:
|
||||||
case 1:
|
case 1:
|
||||||
fitness_list.append(individual.fitness1(self.pm))
|
fitness_list.append(individual.fitness1(self.pm))
|
||||||
case 2:
|
case 2:
|
||||||
fitness_list.append(individual.fitness2(self.pm, self.alpha))
|
fitness_list.append(individual.fitness2(self.pm, self.alpha))
|
||||||
case 3:
|
case 3:
|
||||||
fitness_list.append(individual.fitness3(self.pm))
|
fitness_list.append(individual.fitness3(self.pm))
|
||||||
case _:
|
case _:
|
||||||
fitness_list.append(individual.fitness1(self.pm))
|
fitness_list.append(individual.fitness1(self.pm))
|
||||||
print(self.individuals[max_i(fitness_list)].getChromozome())
|
print(self.individuals[max_i(fitness_list)].getChromozome())
|
||||||
|
|
||||||
def run(self) -> None:
|
def run(self) -> None:
|
||||||
"""
|
"""
|
||||||
Boucle principale
|
Boucle principale
|
||||||
"""
|
"""
|
||||||
for i in range(self.ng):
|
for i in range(self.ng):
|
||||||
self.select()
|
self.select()
|
||||||
self.reproduct()
|
self.reproduct()
|
||||||
self.mutate()
|
self.mutate()
|
||||||
self.print_best()
|
self.print_best()
|
||||||
|
|
||||||
class Individual:
|
class Individual:
|
||||||
"""
|
"""
|
||||||
Classe qui représente les individuts de la population (les solutions potentielles)
|
Classe qui représente les individuts de la population (les solutions potentielles)
|
||||||
"""
|
"""
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.chromozome = ""
|
self.chromozome = ""
|
||||||
|
|
||||||
def setChromozome(self, c: str) -> None:
|
def setChromozome(self, c: str) -> None:
|
||||||
self.chromozome = c
|
self.chromozome = c
|
||||||
|
|
||||||
def getChromozome(self) -> str:
|
def getChromozome(self) -> str:
|
||||||
return self.chromozome
|
return self.chromozome
|
||||||
|
|
||||||
def randomize(self, l) -> None:
|
def randomize(self, l) -> None:
|
||||||
"""
|
"""
|
||||||
Methode qui change la valeur d'un chromozome pour une valeur aléatoire
|
Methode qui change la valeur d'un chromozome pour une valeur aléatoire
|
||||||
"""
|
"""
|
||||||
new = ""
|
new = ""
|
||||||
for i in range(l):
|
for i in range(l):
|
||||||
new += chr(random.randint(0, 255))
|
new += chr(random.randint(0, 255))
|
||||||
self.chromozome = new
|
self.chromozome = new
|
||||||
|
|
||||||
def fitness1(self, pm) -> int:
|
def fitness1(self, pm) -> int:
|
||||||
"""
|
"""
|
||||||
Première methode de fitness, fait la somme des différences entre les codages des caractères des deux chaînes.
|
Première methode de fitness, fait la somme des différences entre les codages des caractères des deux chaînes.
|
||||||
"""
|
"""
|
||||||
sum = 0
|
sum = 0
|
||||||
for i in range(len(self.chromozome)):
|
for i in range(len(self.chromozome)):
|
||||||
sum += abs(ord(self.chromozome[i]) - ord(pm[i]))
|
sum += abs(ord(self.chromozome[i]) - ord(pm[i]))
|
||||||
return -sum
|
return -sum
|
||||||
|
|
||||||
def fitness2(self, pm, alpha) -> int:
|
def fitness2(self, pm, alpha) -> int:
|
||||||
"""
|
"""
|
||||||
Deuxième methode de fitness qui compte les caractères bien placés et mal placés et qui renvoie un int pondéré par alpha
|
Deuxième methode de fitness qui compte les caractères bien placés et mal placés et qui renvoie un int pondéré par alpha
|
||||||
"""
|
"""
|
||||||
match = 0
|
match = 0
|
||||||
missed_placed = 0
|
missed_placed = 0
|
||||||
for i in range(len(self.chromozome)):
|
for i in range(len(self.chromozome)):
|
||||||
if self.chromozome[i] == pm[i]:
|
if self.chromozome[i] == pm[i]:
|
||||||
match += 1
|
match += 1
|
||||||
else:
|
else:
|
||||||
missed_placed += 1
|
missed_placed += 1
|
||||||
return match + alpha * missed_placed
|
return match + alpha * missed_placed
|
||||||
|
|
||||||
def fitness3(self, pm) -> int:
|
def fitness3(self, pm) -> int:
|
||||||
"""
|
"""
|
||||||
Troisième methode de fitness qui utilise la distance de Levenshtein
|
Troisième methode de fitness qui utilise la distance de Levenshtein
|
||||||
"""
|
"""
|
||||||
return -Levenshtein.distance(self.chromozome, pm)
|
return -Levenshtein.distance(self.chromozome, pm)
|
||||||
|
|
||||||
def mutate(self) -> None:
|
def mutate(self) -> None:
|
||||||
"""
|
"""
|
||||||
Methode qui change un des caractères du chromozome
|
Methode qui change un des caractères du chromozome
|
||||||
"""
|
"""
|
||||||
new = list(self.chromozome)
|
new = list(self.chromozome)
|
||||||
new[random.randint(0, len(new) - 1)] = chr(random.randint(0, 255))
|
new[random.randint(0, len(new) - 1)] = chr(random.randint(0, 255))
|
||||||
self.chromozome = "".join(new)
|
self.chromozome = "".join(new)
|
||||||
|
|
|
@ -4,194 +4,196 @@ import random
|
||||||
import Levenshtein
|
import Levenshtein
|
||||||
|
|
||||||
def min_i(array: list[int]) -> int:
|
def min_i(array: list[int]) -> int:
|
||||||
min_val = array[0]
|
min_val = array[0]
|
||||||
min_i = 0
|
min_i = 0
|
||||||
for i in range(len(array)):
|
for i in range(len(array)):
|
||||||
if array[i] < min_val:
|
if array[i] < min_val:
|
||||||
min_val = array[i]
|
min_val = array[i]
|
||||||
min_i = i
|
min_i = i
|
||||||
return min_i
|
return min_i
|
||||||
|
|
||||||
def max_i(array: list[int]) -> int:
|
def max_i(array: list[int]) -> int:
|
||||||
max_val = array[0]
|
max_val = array[0]
|
||||||
max_i = 0
|
max_i = 0
|
||||||
for i in range(len(array)):
|
for i in range(len(array)):
|
||||||
if array[i] > max_val:
|
if array[i] > max_val:
|
||||||
max_val = array[i]
|
max_val = array[i]
|
||||||
max_i = i
|
max_i = i
|
||||||
return max_i
|
return max_i
|
||||||
|
|
||||||
def new_population(pm, ng, n, ts, tm, alpha, fm):
|
def new_population(pm, ng, n, ts, tm, alpha, fm):
|
||||||
"""
|
"""
|
||||||
fonction qui renvoie une nouvelle population
|
fonction qui renvoie une nouvelle population
|
||||||
"""
|
"""
|
||||||
population = {
|
population = {
|
||||||
"individuals": [new_individual() for i in range(n)],
|
"individuals": [new_individual() for i in range(n)],
|
||||||
"pm": pm,
|
"pm": pm,
|
||||||
"ng": ng,
|
"ng": ng,
|
||||||
"l": len(pm),
|
"l": len(pm),
|
||||||
"n": n,
|
"n": n,
|
||||||
"ts": ts,
|
"ts": ts,
|
||||||
"tm": tm,
|
"tm": tm,
|
||||||
"alpha": alpha,
|
"alpha": alpha,
|
||||||
"fm": fm
|
"fm": fm
|
||||||
}
|
}
|
||||||
|
|
||||||
for individual in population["individuals"]:
|
for individual in population["individuals"]:
|
||||||
randomize(individual, 4, 30)
|
randomize(individual, 4, 30)
|
||||||
|
|
||||||
return population
|
return population
|
||||||
|
|
||||||
def new_individual():
|
def new_individual():
|
||||||
"""
|
"""
|
||||||
fonction qui renvoie un nouvel individu
|
fonction qui renvoie un nouvel individu
|
||||||
"""
|
"""
|
||||||
return {
|
return {
|
||||||
"chromozome": ""
|
"chromozome": ""
|
||||||
}
|
}
|
||||||
|
|
||||||
def randomize(individual, min_l, max_l) -> str:
|
def randomize(individual, min_l, max_l) -> str:
|
||||||
"""
|
"""
|
||||||
Methode qui change la valeur d'un chromozome pour une valeur aléatoire
|
Methode qui change la valeur d'un chromozome pour une valeur aléatoire
|
||||||
"""
|
"""
|
||||||
new = ""
|
new = ""
|
||||||
for i in range(random.randint(min_l, max_l)):
|
for i in range(random.randint(min_l, max_l)):
|
||||||
new += chr(random.randint(0, 255))
|
new += chr(random.randint(0, 255))
|
||||||
individual["chromozome"] = new
|
individual["chromozome"] = new
|
||||||
|
|
||||||
def fitness1(individual, pm) -> int:
|
def fitness1(individual, pm) -> int:
|
||||||
"""
|
"""
|
||||||
Première methode de fitness, fait la somme des différences entre les codages des caractères des deux chaînes.
|
Première methode de fitness, fait la somme des différences entre les codages des caractères des deux chaînes.
|
||||||
"""
|
"""
|
||||||
sum = 0
|
sum = 0
|
||||||
for i in range(len(individual["chromozome"])):
|
for i in range(len(individual["chromozome"])):
|
||||||
if i < len(pm) and i < len(individual["chromozome"]):
|
if i < len(pm) and i < len(individual["chromozome"]):
|
||||||
sum += abs(ord(individual["chromozome"][i]) - ord(pm[i]))
|
sum += abs(ord(individual["chromozome"][i]) - ord(pm[i]))
|
||||||
return -sum
|
return -sum
|
||||||
|
|
||||||
def fitness2(individual, pm, alpha) -> int:
|
def fitness2(individual, pm, alpha) -> int:
|
||||||
"""
|
"""
|
||||||
Deuxième methode de fitness qui compte les caractères bien placés et mal placés et qui renvoie un int pondéré par alpha
|
Deuxième methode de fitness qui compte les caractères bien placés et mal placés et qui renvoie un int pondéré par alpha
|
||||||
"""
|
"""
|
||||||
match = 0
|
match = 0
|
||||||
missed_placed = 0
|
missed_placed = 0
|
||||||
for i in range(len(individual["chromozome"])):
|
for i in range(len(individual["chromozome"])):
|
||||||
if i >= len(pm):
|
if i >= len(pm):
|
||||||
missed_placed += len(individual["chromozome"]) - len(pm)
|
missed_placed += len(individual["chromozome"]) - len(pm)
|
||||||
break
|
break
|
||||||
elif individual["chromozome"][i] == pm[i]:
|
elif individual["chromozome"][i] == pm[i]:
|
||||||
match += 1
|
match += 1
|
||||||
else:
|
else:
|
||||||
missed_placed += 1
|
missed_placed += 1
|
||||||
if len(pm) > len(individual["chromozome"]):
|
if len(pm) > len(individual["chromozome"]):
|
||||||
missed_placed += len(pm) - len(individual["chromozome"])
|
missed_placed += len(pm) - len(individual["chromozome"])
|
||||||
return match + alpha * missed_placed
|
return match + alpha * missed_placed
|
||||||
|
|
||||||
def fitness3(individual, pm) -> int:
|
def fitness3(individual, pm) -> int:
|
||||||
"""
|
"""
|
||||||
Troisième methode de fitness qui utilise la distance de Levenshtein
|
Troisième methode de fitness qui utilise la distance de Levenshtein
|
||||||
"""
|
"""
|
||||||
return -Levenshtein.distance(individual["chromozome"], pm)
|
return -Levenshtein.distance(individual["chromozome"], pm)
|
||||||
|
|
||||||
def get_fitness(population, individual) -> int:
|
def get_fitness(population, individual) -> int:
|
||||||
match population["fm"]:
|
match population["fm"]:
|
||||||
case 1:
|
case 1:
|
||||||
return fitness1(individual, population["pm"])
|
return fitness1(individual, population["pm"])
|
||||||
case 2:
|
case 2:
|
||||||
return fitness2(individual, population["pm"], population["alpha"])
|
return fitness2(individual, population["pm"], population["alpha"])
|
||||||
case 3:
|
case 3:
|
||||||
return fitness3(individual, population["pm"])
|
return fitness3(individual, population["pm"])
|
||||||
case _:
|
case _:
|
||||||
return fitness1(individual, population["pm"])
|
return fitness1(individual, population["pm"])
|
||||||
|
|
||||||
def get_fitness_list(population):
|
def get_fitness_list(population):
|
||||||
fitness_list = []
|
fitness_list = []
|
||||||
for individual in population["individuals"]:
|
for individual in population["individuals"]:
|
||||||
fitness_list.append(get_fitness(population, individual))
|
fitness_list.append(get_fitness(population, individual))
|
||||||
return fitness_list
|
return fitness_list
|
||||||
|
|
||||||
def get_best(population):
|
def get_best(population):
|
||||||
"""
|
"""
|
||||||
Methode qui renvoie le meilleur individu de la population
|
Methode qui renvoie le meilleur individu de la population
|
||||||
"""
|
"""
|
||||||
fitness_list = get_fitness_list(population)
|
fitness_list = get_fitness_list(population)
|
||||||
return population["individuals"][max_i(fitness_list)]
|
return population["individuals"][max_i(fitness_list)]
|
||||||
|
|
||||||
def print_best(population) -> None:
|
def print_best(population) -> None:
|
||||||
"""
|
"""
|
||||||
Methode qui affiche le meilleur individu de la population
|
Methode qui affiche le meilleur individu de la population
|
||||||
"""
|
"""
|
||||||
print(get_best(population)["chromozome"])
|
print(get_best(population)["chromozome"])
|
||||||
|
|
||||||
def select(population) -> None:
|
def select(population) -> None:
|
||||||
"""
|
"""
|
||||||
Methode qui sélectionne les meilleurs individus
|
Methode qui sélectionne les meilleurs individus
|
||||||
"""
|
"""
|
||||||
fitness_list = get_fitness_list(population)
|
fitness_list = get_fitness_list(population)
|
||||||
for i in range(int((1 - population["ts"]) * population["n"])):
|
for i in range(int((1 - population["ts"]) * population["n"])):
|
||||||
least = min_i(fitness_list)
|
least = min_i(fitness_list)
|
||||||
fitness_list.pop(least)
|
fitness_list.pop(least)
|
||||||
population["individuals"].pop(least)
|
population["individuals"].pop(least)
|
||||||
|
|
||||||
def get_two_random_individuals(population):
|
def get_two_random_individuals(population):
|
||||||
i = random.randint(0, len(population["individuals"]) - 1)
|
i = random.randint(0, len(population["individuals"]) - 1)
|
||||||
j = random.randint(0, len(population["individuals"]) - 1)
|
j = random.randint(0, len(population["individuals"]) - 1)
|
||||||
while i == j:
|
while i == j:
|
||||||
j = random.randint(0, len(population["individuals"]) - 1)
|
j = random.randint(0, len(population["individuals"]) - 1)
|
||||||
return (population["individuals"][i], population['individuals'][j])
|
return (population["individuals"][i], population['individuals'][j])
|
||||||
|
|
||||||
def reproduct(population) -> None:
|
def reproduct(population) -> None:
|
||||||
"""
|
"""
|
||||||
Methode qui reproduit les individus entre eux jusqu'à obtenir une population de taille N
|
Methode qui reproduit les individus entre eux jusqu'à obtenir une population de taille N
|
||||||
"""
|
"""
|
||||||
new = []
|
new = []
|
||||||
while len(population["individuals"]) + len(new) != population["n"]:
|
while len(population["individuals"]) + len(new) != population["n"]:
|
||||||
indivi_1, indivi_2 = get_two_random_individuals(population)
|
indivi_1, indivi_2 = get_two_random_individuals(population)
|
||||||
|
|
||||||
avg = (len(indivi_1) + len(indivi_2)) // 2
|
avg = (len(indivi_1) + len(indivi_2)) // 2
|
||||||
cut = random.randint(avg // 3, 2 * avg // 3)
|
cut = random.randint(avg // 3, 2 * avg // 3)
|
||||||
while cut > len(indivi_1) or cut > len(indivi_2):
|
while cut > len(indivi_1) or cut > len(indivi_2):
|
||||||
cut = random.randint(avg // 3, 2 * avg // 3)
|
cut = random.randint(avg // 3, 2 * avg // 3)
|
||||||
|
|
||||||
new_chromozome = indivi_1["chromozome"][:cut] + indivi_2["chromozome"][cut:]
|
new_chromozome = indivi_1["chromozome"][:cut] + indivi_2["chromozome"][cut:]
|
||||||
child = new_individual()
|
child = new_individual()
|
||||||
child["chromozome"] = new_chromozome
|
child["chromozome"] = new_chromozome
|
||||||
new.append(child)
|
new.append(child)
|
||||||
|
|
||||||
population["individuals"] += new
|
population["individuals"] += new
|
||||||
|
|
||||||
def mutate(individual) -> None:
|
def mutate(individual) -> None:
|
||||||
"""
|
"""
|
||||||
Methode qui change un des caractères du chromozome
|
Methode qui change un des caractères du chromozome
|
||||||
"""
|
"""
|
||||||
new = list(individual["chromozome"])
|
new = list(individual["chromozome"])
|
||||||
dice = random.randint(1,3)
|
dice = random.randint(1, 6)
|
||||||
if dice == 1 and len(new) < 30:
|
if dice == 1 and len(new) < 30:
|
||||||
new.insert(random.randint(0, len(new) - 1), chr(random.randint(0, 255)))
|
new.insert(random.randint(0, len(new) - 1), chr(random.randint(0, 255)))
|
||||||
elif dice == 2 and len(new) > 4:
|
elif dice == 2 and len(new) > 4:
|
||||||
new.pop(random.randint(0, len(new) - 1))
|
new.pop(random.randint(0, len(new) - 1))
|
||||||
else :
|
else :
|
||||||
new[random.randint(0, len(new) - 1)] = chr(random.randint(0, 255))
|
new[random.randint(0, len(new) - 1)] = chr(random.randint(0, 255))
|
||||||
individual["chromozome"] = "".join(new)
|
individual["chromozome"] = "".join(new)
|
||||||
|
|
||||||
def mutate_pop(population) -> None:
|
def mutate_pop(population) -> None:
|
||||||
"""
|
"""
|
||||||
Methode qui mute une partie de la population selon le taut de mutation
|
Methode qui mute une partie de la population selon le taut de mutation
|
||||||
"""
|
"""
|
||||||
mutated = []
|
mutated = []
|
||||||
for i in range(int(population["tm"] * population["n"])):
|
for i in range(int(population["tm"] * population["n"])):
|
||||||
to_mutate = random.randint(0, population["n"] - 1)
|
to_mutate = random.randint(0, population["n"] - 1)
|
||||||
while to_mutate in mutated:
|
while to_mutate in mutated:
|
||||||
to_mutate = random.randint(0, population["n"] - 1)
|
to_mutate = random.randint(0, population["n"] - 1)
|
||||||
mutate(population["individuals"][to_mutate])
|
mutate(population["individuals"][to_mutate])
|
||||||
mutated.append(to_mutate)
|
mutated.append(to_mutate)
|
||||||
|
|
||||||
def run(population) -> None:
|
def run(population) -> int:
|
||||||
"""
|
"""
|
||||||
Boucle principale
|
Boucle principale
|
||||||
"""
|
"""
|
||||||
for i in range(population["ng"]):
|
for i in range(population["ng"]):
|
||||||
select(population)
|
if get_best(population)["chromozome"] == population["pm"]:
|
||||||
reproduct(population)
|
return i
|
||||||
mutate_pop(population)
|
select(population)
|
||||||
print_best(population)
|
reproduct(population)
|
||||||
|
mutate_pop(population)
|
||||||
|
return population["ng"]
|
||||||
|
|
1
main.py
1
main.py
|
@ -31,6 +31,7 @@ def main() -> None:
|
||||||
# imperative version ++
|
# imperative version ++
|
||||||
pop = libppimp.new_population(PM, NG, N, TS, TM, ALPHA, FITNESS_METHOD)
|
pop = libppimp.new_population(PM, NG, N, TS, TM, ALPHA, FITNESS_METHOD)
|
||||||
libppimp.run(pop)
|
libppimp.run(pop)
|
||||||
|
print(libppimp.get_best(pop)["chromozome"])
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|
59
tests.py
59
tests.py
|
@ -1,59 +0,0 @@
|
||||||
# fichier de tests du projet
|
|
||||||
|
|
||||||
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!"
|
|
||||||
# NG = 2000
|
|
||||||
N = 400
|
|
||||||
TS = 0.5
|
|
||||||
TM = 0.25
|
|
||||||
ALPHA = 0.5
|
|
||||||
FITNESS_METHOD = 3
|
|
||||||
|
|
||||||
fitness_ng = []
|
|
||||||
all_ng = []
|
|
||||||
|
|
||||||
for i in range(1, 11):
|
|
||||||
NG = i * 200
|
|
||||||
all_ng.append(NG)
|
|
||||||
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 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()
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue