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 :
Il comporte 3 onglets.
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.
create-turtles 5 [ setxy random-xcor random-ycor]
set size 2
puis set color red
puis set shape ''wolf''
(toutes les formes et les couleurs disponibles peuvent se trouver dans le menu tools en farfouillant).
ask turtle 1 [set color blue]
. Que constatez-vous ?
ask turtles [set color green]
. Quelle est la différence avec la commande précédente ?
ask turtles [set color random 140]
. Que constatez-vous ? Créez 100 tortues de couleur aléatoire avedc random 10
dans la commande précedente.
set pcolor green
fd 1
puis rt 45 puis fd 1 puis lt 45 puis fd 1.
rt 45
fd 1
lt 45
pen-down
puis fd 1
. Vous pouvez donc en déduire ce que fait la commande pen-up
.
clear-all
.create-turtles nombre [ setxy random-xcor random-ycor]
.
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.
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.
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 :
ask turtles [set longueur longueur + 1]
si la procédure est une procédure observer.
set longueur longueur + 1
si la procédure est une procédure turtles.
repeat
.repeat 10 [truc]
répètera 10 fois les instructions truc
. Il peut y avoir un appel de procédure dans truc
.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.
Dans le command center, taper :
ask patches [set pcolor random 140]
set pcolor random 140
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 :
set pcolor black
;
set pcolor white
.
ask patches [ifelse random-float 100.0 < densite [set pcolor white][set pcolor black]]
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
) :
set couleur random 3 ;; met la couleur à 0, 1 ou 2 (3 exclu)
ifelse couleur = 0 [set pcolor white][ifelse couleur = 1 [set pcolor black][set pcolor pink]]
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).
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 :
À 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):
Comme dans les programmes avec les tortues, on va avoir un bouton setup
et un bouton go
.
Setup
: facile, il s'agit de créer des patches de couleur aléatoire noire ou blanche, c'est-à-dire vivantes/mortes, avec le curseur de densité, comme on a déjà fait.
Go
: plus difficile.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 :
patches-own [
vivant? ;; pour indiquer si la cellule est vivante ou non
nombreVoisinsVivants ;; comme son nom l'indique...
]
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.
to compter-voisins...end
set
(voir les spirales), qu'on va ici mélanger avec count
. Ecrire l'instruction demandée dans cette procédure, qui compte le nombre de voisins vivants et met à jour la variable nombreVoisinsVivants
.
to mettre-a-jour... end
vivant?
, ainsi que la couleur du patch.!=
.
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 :
ask patch 0 1 [set pcolor black]
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.
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.
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 cellules ont trois états : en feu (blanche), réfractaire (rouge), et morte (noires).
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 ».
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 ».
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 :
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
:
create-turtle
, forcer la direction avec face one-of neighbors4
. La tortue est ainsi dirigée vers un des quatre points cardinaux.
go
:
fd
(pour avancer), rt
et lt
(pour tourner).
set pcolor
, ifelse
…
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é).
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 :
énergie
, et les patchs une variable compteur_de_temps
. Les patchs seront marrons sans herbe et vert avec.set energie random (2 * gain_mouton_herbe)
).go
, on écrira plusieurs fonctions :
manger_herbe
qui diminue l’énergie de 1 à chaque déplacement s’il n’y a pas d’herbe sur le patch, sinon augmente l’énergie du mouton suivant le gain, remet le compteur de temps du patch à 0, et la couleur à marron.
reproduction
. Si un nombre aléatoire entre 0 et 100 est plus petit que le pourcentage de reproduction, alors la tortue/mouton se reproduit dans un patch adjacent. La syntaxe est hatch 1 [ rt random-float 360 fd 1 ]
. L’énergie du parent est divisée par deux. Vous remarquerez que la reproduction se fait ici par parthénogénèse (le mouton se divise en 2, comme une amibe !).
mort
: si l’énergie est négative, le mouton meurt. Syntaxe : if energy < 0 [ die ]
.
herbe_pousse
: si la couleur du patch est marron, on augmente le compteur de temps, et si ce compteur est supérieur ou égal au temps nécessaire à la repousse, on met le patch en vert.
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 :
breed [ moutons mouton ]
; il y a le pluriel et le singulier comme turtle et turtles
breed [ loup loups ]
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