Accueil ISN - TS ICN - 2nde Maths - TS Liens

Initiation aux systèmes multi-agents

Découverte de NetLogo

Qu'est qu'un système multi-agents ?

Netlogo est un programme permettant de faire du Système Multi Agents (SMA). Un agent (une tortue en Netlogo) interagit avec les autres agents, et aussi avec son environnement (formé de patches en Netlogo). Les agents peuvent être de différents types, ainsi que les patchs. On peut par exemple ainsi :

Les SMA sont très bien représentés au cinéma dans Matrix, avec les robots insectoïdes du monde « réel ».

Première utilisation de NetLogo

Lancer le programme. Si le raccourci ne fonctionne pas, on peut le lancer en ligne.

Le progamme

Il comporte 3 onglets.

Les commandes

Pour se familiariser avec le langage de programmation, on va d’abord rentrer les instructions/commandes une par une dans le centre de commandes.
Vous avez tout en bas un choix possible entre observer, turtles, patches et link. Laissez (ou choisissez) observer. Pour chacune des commandes suivantes, observez l'effet. Notez dans un document LibreOffice les effets de chaque commande. Ce document nommé commandes_Netlogo_votre nom sera à me rendre par email, dès la fin de la première séance. Vous le complèterez au fur et à mesure des séances, il fera ainsi office d'aide mémoire lorsque vous ferez des programmes plus complexes. Toutes les instructions en format code doivent être expliquées dans ce document.

Les outils

Rajoutez un curseur (choisir slider en haut à gauche, dans le menu déroulant, puis cliquer sur le bouton Add). Appelez la variable globale associée nombre.
En vous inspirant de ce que vous avez déjà fait, tracez des carrés avec nombre tortues. La syntaxe pour la création est create-turtles nombre [ setxy random-xcor random-ycor]

.

Premier programme

Merci à Jacques Ferber, professeur à L'UM II, pour ce point de départ.

Ouvrir le programme « simple_aleatoire.nlogo », dans le dossier Documents>Devoirs>Mandon. Vous pouvez aussi le télécharger. Enfin, vous pouvez également copier-coller le code ci-dessous, il faudra alors rajouter des boutons dans l'onglet Interface (voir avec le proofesseur, ça sera forcément plus long qu'une des solutions précédentes).
Je vous conseille d'enregistrer ce programme dans un dossier de travail « Documents>Netlogo », ainsi que tous les programmes que vous créerez.
Le code est ci-dessous, vous pouvez le voir également dans l’onglet code.
Lancez-le, testez son fonctionnement.

Structure du langage

Voici le code :
to setup
   ;; si ca ne marche pas (anciennes versions de NetLogo)
   ;; il faut peut-etre mettre la commande
   ;; __clear-all-and-reset-ticks
   ;; au début de la procedure, et enlever
   ;; clear-all ainsi que reset-ticks

   clear-all
   set-default-shape turtles "bug"

   ;; place les tortues de maniere aleatoire
   create-turtles nombre [
     set color red
     setxy random-xcor random-ycor
     set size 2
   ]
   reset-ticks
end

to agiter
   rt random 50 ;; angle aleatoire entre 0 et 50 degres
   lt random 50
end

to go
   ask turtles[
     agiter
     fd 1 ]
  tick ;; fait un tick d'horloge, finit la boucle
         ;;et revient au debut du go
end

Examinons le programme simple_aleatoire.nlogo dans l'onglet Code ou ci-dessus.
Les procédures commencent par to et finissent par end. Il y a deux procédures principales, le setup et le go (qui équivalent au setup et au loop si vous avez déjà travaillé sous Arduino).
On construit d'autres procédures pour les actions des tortues et les modifications des patchs. Ici il y a une procédure agiter, qui fait se mouvoir les tortues.
Dans l’onglet Interface, il y a également deux boutons en plus : setup et go. Avec un clic droit (Edit…), regardez les propriétés desdits boutons.
En se basant sur cet exemple, créer le programme « carrés », qui dessine des carrés automatiquement. Conservez indent automatically coché, cela rendra votre code plus lisible. Vous pouvez vérifier la syntaxe du code avec le bouton check.
Faites ensuite un programme « triangles équilatéraux ».
Rendez les programmes faits sous le nom : carres_votreNom.nlogo (ou triangles !). Par email ou dans le dossier Devoirs>Mandon.

Les variables

Vous allez modifier le programme qui trace des carrés pour tracer maintenant des spirales.
Pour cela, il va falloir créer une variable qui donne la longueur du côté de la spirale. En effet cette longueur varie au cours du temps.
Les variables sont déclarées au début du code, sous la syntaxe : turtles-own [longueur]. Ici on a créé pour chaque tortue une variable longueur.
Puis, au bon endroit dans le code, pour augmenter la longueur de 1 on tape :

Une fois que votre programme est fonctionnel, vous pouvez l’améliorer en faisant des spirales finies.
Pour cela, il faut décocher la case forever dans le bouton go, et utiliser un repeat.
Par exemple repeat 10 [truc] répètera 10 fois les instructions truc. Il peut y avoir un appel de procédure dans truc.
Modifiez votre programme afin qu’il fasse des spirales finies.
Le programme pourra faire les spirales une seule fois, ou bien une fois les spirales faites, effacer et recommencer.
Rendez le programme fait sous le nom : spirales_finies_votreNom.nlogo, par email ou dans le dossier Devoirs>Mandon.

Les patches

Contrairement aux tortues, les patches ne sont pas mobiles : ce sont les carrés qui constituent le « monde ».. Mais comme les tortues, ils ont des propriétés qui peuvent évoluer.
On peut modifier la taille du monde dans settings (onglet interface), ainsi que la taille des patches. Pour les exercices que l'on va faire, il vaut mieux créer des patches plus petits (taille 5 par exemple), avec un monde de taille 50.

Quelques commandes

Dans le command center, taper :

Créer un curseur avec comme variable « densité » (ne pas mettre d'accent comme toujours en informatique).
On va créer des patches de couleur soit noire soit blanche, avec une densité fixée par le curseur.
La commande est, dans le command center avec patches :
   ifelse random-float 100.0 < densite [set pcolor black][set pcolor white]
Explications :
ifelse est une instruction si... sinon. Si une certaine condition est réalisée, on fait quelque chose, sinon autre chose. Le sinon est facultatif.
La condition est ici random-float 100.0 < densite.
Random-float 100,0 tire un nombre a virgule au hasard, entre 0 et 100 (en fait entre 0 et 99,99999...).
On teste ensuite si ce nombre est plus petit ou pas que la densité demandée :

On remarque que les instructions à exécuter sont entre crochets.
Si on veut exécuter cette commande en tant qu'observateur, on rajoute :
   ask patches [ifelse random-float 100.0 < densite [set pcolor white][set pcolor black]]

Variables et patches

Comment avoir trois couleurs de patches au hasard ?

Dans l'onglet code, taper patches-own [couleur] : chaque patch aura sa variable couleur.
Dans le command center, soit patches soit observer (mettre ou non ask patches) :

Dans votre document LibreOffice commandes_Netlogo_votre nom, expliquer le fonctionnement de la dernière instruction.

Un objet (tortue ou patch) peut aussi observer ce qu'il y a autour de lui. Nous allons avoir besoin de compter, l'instruction dans le command center observateur est :
  count patches with [pcolor = white]
Pour compter autour d'un patch bien précis(ou d'une tortue), l'observateur peut demander :
  ask patch 0 0 [show count neighbors with [pcolor = white]]
Ici on a compté le nombre de cellules blanches dans les huit cellules autour de l'origine (coordonnées 0 0).

Les programmes : patches

Le jeu de la vie

Présentation et travail sur papier

Le nom est trompeur, ce n'est pas un jeu ; on dit que c'est un jeu « à zéro joueur », puisqu'il joue tout seul ! C'est ce que l'on appelle un automate cellulaire, c'est à dire un processus qui évolue de lui-même, par étapes. Chaque étape correspond à un tick d'horloge. Les cellules sont sur une grille régulière et possèdent un nombre fini d'états, entre lesquels elles évoluent. Les règles d'évolution sont très simples en général, mais donnent des comportements très complexes et souvent imprévisibles.
Dans le jeu de la vie, les cellules sont représentées par les patches. Elles sont soient mortes soient vivantes (en général vivantes en noir ou en couleur, mortes en blanc).
L'état d'une cellule à l'étape suivante est entièrement déterminé par l'état des 8 cellules qui l'entoure :

Exemples :

À la main, donner l'étape suivante de la configuration ci dessous (on peut marquer d'un point vert toutes les cellules qui vont naître à l'étape suivante):

Programmation

Comme dans les programmes avec les tortues, on va avoir un bouton setup et un bouton go.

Pour éviter cette erreur, il va donc falloir dans un premier temps examiner toutes les cellules pour prévoir leur état à l'étape suivante, et ensuite seulement modifier leur état.
Cela nécessite trois choses :

Pour garder en mémoire une donnée, on crée une variable comme on l'a fait pour le programme du dessin des spirales.
Pour les variables on écrira au début du programme :
   patches-own [
   vivant? ;; pour indiquer si la cellule est vivante ou non
   nombreVoisinsVivants ;; comme son nom l'indique...
   ]

La variable vivant? vaut true ou false. La variable nombreVoisinsVivants est un nombre entier (compris entre 0 et 8 ici).

Dans le « go », il y aura les deux parties :
to go
   ask patches [compter-voisins]
   ask patches [mettre-a jour]
   tick
end

On crée deux procédures supplémentaires.

Programmer le jeu de la vie, et tester son fonctionnement. Que se passe-t-il souvent ?

Un bouton supplémentaire

Rajouter un deuxième bouton de setup : le setup-glider
. On va créer une nouvelle procédure associée : to setup-glider... end
Dans cette procédure, mettre tous les patches à blanc (morts), puis tracer la figure du glider (cf ci-dessous). Je vous rappelle que l’on peut demander à un patch spécifique une action, comme ceci :


Tester le fonctionnement du jeu de la vie avec le glider (et après regarder la traduction de glider en français !).
Rendez le programme sous le nom jeu_de_la_vie_votreNom.nlogo, par email ou dans le dossier Devoirs>Mandon.

Variantes du jeu de la vie

Vous pouvez programmer facilement une ou plusieurs de ces variantes à partir du jeu de la vie originel, seules les conditions de changement d’état vivant/mort sont à modifier. Rendez les programmes que vous faites.

Day & Night

Une cellule morte y naît à l'étape suivante si elle est entourée de 3, 6, 7 ou 8 voisines vivantes, une cellule vivante survit à l'étape suivante si elle est entourée de 3, 4, 6, 7 ou 8 cellules vivantes.

High Life

Une cellule morte y naît à l'étape suivante si elle est entourée de 3 ou 6 voisines vivantes, une cellule vivante survit à l'étape suivante si elle est entourée de deux ou trois cellules vivantes.
Vous pouvez inverser la condition précédente (c’est-à-dire répondre à la question : quand est-ce qu’une cellule meurt ?), pour que la programmation soit plus facile.
Essayer les deux figures ci-dessous en démarrage, elles donnent un résultat intéressant. La commande pour exécuter des instructions pour un patch donné par ses coordonnées est : ask patch coord_x coord_y […]

Les automates cellulaires à plusieurs états

les cellules de ces automates ont plus de deux états possibles, par exemple entre vivant et mort il peut y avoir zombie. Plutôt que vrai/faux, on codera les états sous forme d'un nombre. S'il y a trois états on les codera 0/1/2.
Programmez au moins « le cerveau de Brian », sous le nom cerveau_Brian_votreNom.nlogo , à rendre par email ou sur Devoirs/Mandon.

Le cerveau de Brian est en feu

Les cellules ont trois états : en feu (blanche), réfractaire (rouge), et morte (noires).

Immigration

A REPRENDRE : Immigration fonctionne exactement de la même façon que le jeu de la vie, à ceci près qu'il possède trois états, dont deux « vivants ».

Quad Life

QuadLife fonctionne exactement de la même façon que le jeu de la vie, à ceci près qu'il possède cinq états, dont quatre « vivants ».

Les programmes : interactions tortues/patches

La fourmi de Langton

Cet automate cellulaire, qui a des règles très simples, permet de mettre en évidence un comportement « émergent », c’est-à-dire un comportement complexe, imprévisible à partir des règles initiales.
La fourmi est une « turtle » (dans l’optique netlogo), qui si déplace sur les patches du « monde ».
Initialement, tous les patches sont soit noirs soit blancs.
La fourmi peut se déplacer à gauche, à droite, en haut ou en bas d'une case à chaque fois selon les règles suivantes :

Indications pour la programmation

Dans Settings (taille du monde dans l’interface), faire un monde assez grand (coordonnées maximales 120, taille du patch 2 par exemple).
Dans le setup :

Dans le go :

Complément

Faire un bouton alenvers, qui permet de remonter dans le temps et de retrouver la position initiale.
On peut aussi observer ce qui se passe avec un monde non homogène au départ (les patches étant crées comme dans le jeu de la vie, soit noirs, soit blancs, suivant un curseur de donnant la densité).

L'herbe, les moutons, voire les loups

On va chercher à modéliser l’évolution d’une population animale en fonction des ressources (voire la coévolution de deux populations). Pour cet exercice final, utilisez les programmes précédents pour vous guider : je ne vous donne que les nouvelles instructions de codage, à vous de réutiliser les anciennes.
Créer un monde (settings dans interface) de coordonnées maximales 25 et 25, taille du patch 9.
Créer plusieurs curseurs, les valeurs initiales sont proposées entre parenthèses :

Dans le code, les moutons-tortues auront une variable énergie, et les patchs une variable compteur_de_temps. Les patchs seront marrons sans herbe et vert avec.
Les moutons seront blancs, de taille 1,5, avec une énergie aléatoire (par exemple set energie random (2 * gain_mouton_herbe) ).
Dans le go, on écrira plusieurs fonctions : Enfin, dans l’interface, on peut tracer automatiquement les courbes qui montrent l’évolution des populations. Ca se fait avec Add, on choisit plot. On ajoutera deux crayons (pen), l’un pour les moutons, l’autre pour l’herbe (divisée par 4 pour tenir sur le schéma). Syntaxes dans pen update command : plot count sheep et plot grass / 4. Faire varier les paramètres et observer les différents scénarios d’évolution.

Pour ceux qui sont très rapides, on peut rajouter les loups (qui vont manger les moutons).
Dans le code il y aura deux types de tortues, on le précise en écrivant au tout début :

Plutôt que create-turle, on écrira create-moutons et create-loups.
Il y aura des curseurs similaires à ceux des moutons (nombre de loups 50, gain d’énergie 20, taux de reproduction des loups 5 %), ainsi que les fonctions de déplacement, de reproduction et de mort.
Enfin, la procédure lorsque les loups mangent des moutons est celle-ci (à compléter) :
 to manger_moutons
   let prey one-of moutons-here      ; le loup essaie de manger un mouton
   if prey != nobody                 ; le loup a attrapé un mouton ? Si oui
     [ ask prey […]                  ; il le tue
     …]                              ; et son énergie augmente
 end


On complètera également les courbes de population.