Les algorithmes génétiques démystifiés 11
La dernière fois on a assuré la sélection à l’aide d’une piscine d’accouplement (je ne me lasse pas de ce terme…). Aujourd’hui, on peut aller au bout de l’algorithme en ajoutant la reproduction.
La reproduction des phrases
Il n’y a rien de nouveau par rapport à l’algorithme précédent,
c’est peut-être même plus simple. Voici la méthode crossover
, qui
permet d’obtenir un enfant:
Edit du 14 sept 2013 Le code ci-dessus contient une erreur, à la
seconde ligne il faut lire: point = rand(1..@search_value.size)
.
crossover
prends deux chromosomes en entrée (les parents). On définit
un point de croisement au hasard. On utilise ce point de croisement pour
couper les parents en deux parties. Un enfant est produit en concaténant
la première partie du premier parent avec la seconde partie du second
parent. Enfin on renvoie un chromosome, après avoir passer l’enfant/phrase
à la mutation. Voici justement la méthode chargée de la mutation:
La différence avec l’algorithme précédent est que cette fois chaque gène peut muter. Avantage: on est plus proche du phénomène naturel et on pourrait se retrouver avec un chromosome dont 2 ou 3 gènes sont mutants, ça semble bon pour la diversité génétique. Inconvénient: Générer un nombre aléatoire pour chaque gène peut faire tomber les performances si on a un millier de gènes (ou plus) par chromosome et/ou une population importante. Comme je dis d’habitude: «Si c’est de l’informatique, c’est une histoire de compromis».
On peut maintenant créer une méthode next_generation
qui englobe la
sélection et la reproduction:
Je ne vais pas vous faire l’affront d’expliquer cette méthode, vous avez toutes les cartes en main pour la comprendre. Sinon, c’est que j’ai mal fait mon boulot…
Il reste à mettre tout ça ensemble, voici le code complet du programme:
Et voilà le résultat:
[~/genetic]⇒ ruby monkey.rb
...
Generation: 869
[1.0092854259184496, "Mon royaume pour un chevaB"]
[1.0092854259184496, "Mon royaume pour un chevan"]
[1.0092854259184496, "Mon royaume pour un chevaB"]
...
[1.0496568429551878, "Mon royaume pour un cheval"]
...
[1.0092854259184496, "Mon royaume pour un chevan"]
[1.0092854259184496, "Mon royaume pour un chevaB"]
[0.9689140088817118, "Mon royaume pour un chNvaB"]
La prochaine fois on va améliorer notre méthode de sélection pour tenir compte des chiffres après la virgule.
À demain.