Introduction à la programmation
génétique avec Python


Quel joie d'écrire mon premier article sur le site du LABO, et en plus un article plus qu'orienté qui va donner le ton en la matière. Suite à la lecture de l'article de Virtualabs dans System Addict sur la programmation génétique, je me suis dit « Et pourquoi pas moi ? ». Alors voilà, Python et SciTE dehors, j'ai écrit mes premières lignes et tâter de la chose.

Avant de continuer, je tiens à remercier Virtualabs et toute la team de System Addict pour leur travail sur le magazine.

Passons maintenant au coeur du sujet, l'initiation et la présentation « à la mimas » de la programmation génétique. Il faut signaler que je n'ai que peu d'expérience en Python et que c'est la première fois que j'aborde la programmation génétique. Alors, par avance, soyez indulgent à mon égard.

La programmation génétique est la résolution de problèmes complexes en utilisant des éléments simples. Pour faire un parallèle avec la vie réelle, et avoir un exemple moins théorique, nous allons prendre les fourmis et une miette de pain. Le problème qui se pose alors est : « comment est-ce que les fourmis vont mettre cette énorme et appétissante miette de pain dans leur fourmilière ? ». Si vous avez déjà regardé des fourmis, vous connaissez la réponse : elles vont chacune tirer dans leur direction jusqu'à ce que la miette finisse au garde-manger. Simple, non ?!

Nous allons faire presque la même chose ici, sauf que la miette de pain sera remplacée par une équation, et les fourmis par des individus de type YoLaFourmi. Ces individus ont comme particularité d'avoir un gène (une valeur qui servira à résoudre l'équation) et de remplir une fonction (ici ce sera la reproduction pour transmettre leur gène car les YoLaFourmis sont connues pour être de chaudes créatures).

Il nous faut tout d'abord conceptualiser tout ça et créer le monde qui verra évoluer les YoLaFourmi, ou, plus simplement, comment devenir Dieu en moins de dix leçons. Notre monde devra être capable de se peupler d'individu, de tester si l'équation est résolue par un de ses habitants, les YoLaFourmis, et de les faire évoluer vers une autre génération afin que ce monde trouve sa YoLaFourmi.

Le sujet est déjà bien implanté, on sait maintenant que les YoLaFourmis devront user de toutes leurs caractéristiques pour créer une génération suivante capable de réussir là où elles auront échoué. Mais, rassurons-nous, leur libido ne souffre pas de cet échec.

Pour ne pas rendre la lecture du programme complexe, nous aurons une gestion de la génération suivante très légère et peu respectueuse de notre monde : un des parents se transformera en fils et l'autre survivra. Mais comme les deux parents peuvent avoir muté avant d'avoir copuler sauvagement, le parent restant ne sera pas forcément le même qu'à sa naissance. L'âge n'épargne personne, même pas les YoLaFourmis. À moins que ce soit les radiations de Fallout qui soient en cause.

La transmission des gênes est effectuée grâce à l'opération (valeur_parent1 * valeur_parent2) / (valeur_parent1 + valeur_parent2). Des YoLaFourmis peuvent naître spontanément si les parents ne sont pas capables de concevoir, ç-à-d si valeur_parent1 + valeur_parent2 = 0. Cela a du bon d'être un dieu qui créé son monde.

Bien sûr tout ceci sera modélisé en objet dans un script python.

Souvenez-vous avant de lire le code source du programme qu'un monde apparaît et se peuple de YoLaFourmis. Si une Yolafourmi est capable de résoudre l'équation (qui est X^2 - X = 42) alors le monde n'aura plus lieu d'être. Dans le cas contraire, une nouvelle génération de YoLaFourmi voit le jour.

Avertissement : le code source du programme n'est pas à mettre devant tous les yeux car la reproduction en masse peut-être choquante. Bref, d'ici peu devrait voir apparaître la notion "Contains explicit source code" suite à la parution de cet article.

--- genetique.py ---
from random import randint

# ******************************************************************************
class World:
  pop = {}     # La population
  elements = 0 # Le nombre d'éléments peuplant le monde


def __init__(self,elements = 10):
  """ Le constructeur du monde. Restons modestes """
  self.elements = elements
  for i in range(elements):
    self.pop[i]=YoLaFourmi()


def Fornicate(self):
  """ On fait une petite sauterie chez les gens de ce monde """
  self.count = self.count + 1
  print ("Un peu plus tard…")
  for i in range(self.elements/2):
    self.pop[i*2] = self.pop[i*2].ShagWith(self.pop[i*2+1])

def Resolved(self):
  """ Retourne True si la condition de "fin du monde" est atteinte """
  for i in range(self.elements):
    if (self.pop[i].value**2 - self.pop[i].value) == 42:
      print ("**** On trouve %s en %s générations"
              % (self.pop[i].value, self.count))
      return True
  return False


# ******************************************************************************

class YoLaFourmi:
  value = 0

  def __init__(self, value = None):
    if value == None:
      self.value = randint(1,300)
    else:
      self.value = int(value)


def Mutate(self):
  """ Mutations des individus """
  rand = randint(0,20)

  if rand == 1:
    self.value = self.value + 1
  elif rand == 4:
    self.value = self.value - 1
  elif rand == 12:
    self.value = randint(0,20)


def ShagWith(self, partner):
  """ Rencontre chaleureuse entre deux individus """

  # On ajoute un brin de folie au cours de cette vie
  self.Mutate()
  partner.Mutate()

  try:
    fils = YoLaFourmi((self.value * partner.value) /
                      (self.value + partner.value))
  except:
    print("Oups...")
    fils = YoLaFourmi(0) # Génération spontanée. Pop !
  return fils


# ******************************************************************************
# Ici commence l'histoire du monde

myworld = World()
while not myworld.Resolved():
  myworld.Fornicate()

Fabrice "mimas" T.
 


 
Labo - Association Loi 1901 - 04200 PEIPIN - France

Désengagement : Laboskopia se désengage de toute responsabilité quand à l’utilisation ou le mauvais usage qui peut être fait des informations contenues dans son site. Les renseignements contenus dans la publication des Bulletins peuvent changer et évoluer. L'utilisation de ces renseignements constitue l'acceptation des conditions. Toutes utilisations de ces informations se fait au risque de l'utilisateur.