1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
| import random
#Genes des individus
GENES = "KOCR"
NBRE_PRVLT = 100
NOMBRE_INDIVIDUS = 100
POURCENTAGE_ELITE = 0.20
TAUX_MUTATION = 0.01
def generationGene():
return random.choice(GENES)
# Generation d'un individu (Composé de gènes). Le nombre de gène à générer est fonction de la taille du nombre de prélèvement
def generationIndividu():
return [generationGene() for i in range(NBRE_PRVLT)]
# Generation de la population (Composée d'individus) Le nombre d'individus à générer est passé en paramètre
def generationPopulation(nombreIndividus):
return [generationIndividu() for i in range(nombreIndividus)]
# Calcul de l'aptitude d'un individu
def calculAptitude(individu):
aptitude = 0
print(str(individu.count("C")) + "-" + str(individu.count("O")) + "-" + str(individu.count("K")) + "-" + str(individu.count("R")) )
if ( individu.count("C") == 20): aptitude = aptitude + 1
if ( individu.count("O") == 30): aptitude = aptitude + 1
if ( individu.count("K") == 40): aptitude = aptitude + 1
if ( individu.count("R") == 10): aptitude = aptitude + 1
print(aptitude)
return aptitude
# Classement des individus de la population par ordre décroissant d'aptitude. Ce classement inverse est réalisé à l'aide d'une fonction lambda
# Le résultat est un tableau dont la première colonne contient l'individu et la seconde son aptitude.
def classementIndividus(population):
classement_individus = []
for individu in population:
classement_individus.append((individu,calculAptitude(individu)))
return sorted(classement_individus, key=lambda x: x[1], reverse=True)
def generationFuture(population, pourcentageElitisme, tauxMutation):
# 1: On classe les individus de la population passée en paramètre
classement_individus = classementIndividus(population)
# 2: On crée 2 tableaux. L'un contenant l'individu gagnant, l'autre un tableau contenant les individus classés mais sans leur valeur d'aptitude
individu_gagnant = []
individus_classes = []
# 3: Parcours des individus
for individu, aptitude in classement_individus:
# On stock l'individu sans son aptitude dans un nouveau tableau
individus_classes.append(individu)
# Si l'aptitude est au maximum, cela signifie que nous avons trouvé la solution.
if aptitude == 4:
individu_gagnant.append(individu)
if individu_gagnant:
return population, individu_gagnant
# 4: Selection des meilleurs individus (elites) devenant alors parents. Leur nombre est fonction du pourcentage d'élites passé en paramètre
nombreElites = int(len(population) * pourcentageElitisme)
parents = individus_classes[:nombreElites]
# 5: On selectionne d'autres parents pour maintenir la diversité génétique. Cette selection se fait au hasard
# Si la roulette sort une valeur inférieure à 0.05 alors on ajoute l'individus aux parents
for individu in individus_classes[nombreElites:]:
roulette = random.random()
if roulette < 0.05:
parents.append(individu)
# 6: Croisement des parents pour créer une nouvelle génération
nombreDeParentsSelectionnes = len(parents)
nombreEnfantsSouhaites = len(population) - nombreDeParentsSelectionnes
# Le nombre de gènes du père sera égal à la longueur du nombre de prelevement divisé par deux
nombreGenesPere = NBRE_PRVLT // 2
# Le nombre de gènes de la mère sera égal à la longueur du mot - le nombre de gène du père
nombreGenesMere = NBRE_PRVLT - nombreGenesPere
# Tant que nous n'avons pas le nombre d'enfants souhaité,
# On choisi 2 parents au hasard
# On extrait les gènes du père en fonction du nombre déterminé précédemment
# On extrait les gènes de la mère en fonction du nombre déterminé précédemment
# On concatène les deux pour obtenir un enfant
enfants = []
while len(enfants) < nombreEnfantsSouhaites:
pere = random.choice(parents)
mere = random.choice(parents)
enfant = pere[:nombreGenesPere] + mere[nombreGenesMere:]
enfants.append(enfant)
# Mutation génétique de certain enfants
# Cette mutation se fait aussi au hasard. Tant sur le choix de l'individu- Tant sur le gene à modifier
for enfant in enfants:
if random.random() < tauxMutation:
indexGene = int(random.random() * NBRE_PRVLT)
enfant[indexGene] = generationGene()
# Ajout des enfants à la liste des parents pour créer la population
parents.extend(enfants)
return parents, individu_gagnant
# On définit un maximum de générations pour éviter une boucle infinie dans le cas où aucune solution n'est trouvée
MAXIMUM_GENERATIONS = 10000
# Generation d'une population initiale
population = generationPopulation(NOMBRE_INDIVIDUS)
# Execution de l'algorithme génétique
i = 0
individu_gagnant = None
while not individu_gagnant and i < MAXIMUM_GENERATIONS:
population, individu_gagnant = generationFuture(population, POURCENTAGE_ELITE, TAUX_MUTATION)
i = i + 1
if individu_gagnant:
print("Solution trouvée :" + str(individu_gagnant) + " Nb générations = " + str(i))
print("Pourcentage Beurre de Karité : " + str(str(individu_gagnant).count("K")) + "%")
print("Pourcentage Beurre de Coco : " + str(str(individu_gagnant).count("C")) + "%")
print("Pourcentage Huile d'Olive : " + str(str(individu_gagnant).count("O")) + "%")
print("Pourcentage Huile de Ricin : " + str(str(individu_gagnant).count("R")) + "%")
else:
print("Pas de solution trouvée...") |
Partager