<< | NetLogoIndex? | >>
Plan (hide)
1. Avertissement
L'objectif de ce chapitre est de fournir un complément plus didactique que ce qui est présenté en cours. L'approche est par l'exemple cela se lit en testant et en mettant en oeuvre. D'autre part certains concepts peuvent être utilisés alors qu'ils n'ont pas encore été expliqués et développés en cours, mais ils sont généralement nécessaires pour obtenir une application complète. Tout ceci va s'appuyer sur un exemple qui va être développé au fil de l'eau.
2. Le problème
Nous allons essayer de réaliser un petit programme simple permettant de simuler le comportement de deux populations de tortue : les craintives et les agressives. Elles possèdent toutes un cône de vision et elles fuiront ou se rapprocheront en fonction de ce qu'elles perçoivent.
3. Au boulot
La solution va être construite en deux temps :
- Une seule population avec uniquement des tortues craintives ;
- Deux populations.
3.1 Une première version avec une unique population
Commençons par créer un squelette d'interface pour notre petit programme. Si vous regardez les modèles prédéfinis de NetLogo vous constaterez qu'ils ont presque toujours 2 boutons : setup
et go
. Le premier sert à initialiser la simulation et le second à lancer la simulation.
Il faut donc créer le premier bouton setup
. Vous pouvez le faire par l'intermédiaire de l'interface en cliquant sur add
et en sélectionnant Button
si nécessaire.
Dans la partie commands
vous allez donner le nom de la procédure associée au bouton. Cela fixe également l'intitulé par défaut du bouton. Le bouton apparaît en rouge car la procédure associée n'est pas définie.
Complétez votre interface en ajoutant un bouton go
de la même façon.
Nous allons maintenant définir notre procédure setup
qui crée les tortues. Pour cela il faut utiliser l'onglet code
. Les tortues que nous allons représenter sont les craintives.
Une procédure NetLogo permet de définir ses propres commandes. Elle est composée de commandes prédéfinies comme forward
, create-tutles
... que nous verrons au fur et à mesure, mais aussi d'appel à des procédures que vous avez définies et également d'instructions. Le squelette de base est le suivant :
to setup ; On complète avec les commandes et les instructions end
Le ; est sans effet, il permet de commenter le code. Étoffons notre code maintenant :
to setup clear-all ; On fait le ménage create-turtles 100 ; On crée 100 tortues end
Vous pouvez tester en cliquant en revenant dans l'onglet interface
et en cliquant sur setup
. Vous avez alors 100 tortues en tas au milieu de votre world
. Nous avons vu 2 commandes :
clear-all
souvent abrégé enca
qui réinitialise tout ;create-turtles
(ct
) qui crée des tortues.
Pendant que vous êtes sous l'onglet interface
je vous propose de rajouter un slider
qui va nous permettre de fixer la population de tortues craintives.
Plutôt que fixer le nombres de tortue dans le code cela sera déterminé par la valeur du slider
. On va également mieux répartir nos tortues dans le world
.
to setup clear-all ; On fait le ménage create-turtles Trouillardes ; Valeur obtenue par le slider correspondant ask turtles ; On s'adresse à toutes nos tortues [ set xcor random max-pxcor ; On fixe aléatoirement l'abscisse entre 0 et max-pxcor set ycor random max-pycor ; On fixe aléatoirement l'ordonnée entre 0 et max-pycor set heading random 360 ; On fixe aléatoirement l'orientation de la tortue set size 2 ; On fixe la taille set color green ; On fixe la couleur ] end
create-turtles Trouillardes
On créé le nombre de tortues fixé par leslider
correspondant.Trouillardes
est une variable globale connue dans l'ensemble du programme.ask turtles ....
on s'adresse à l'ensemble des tortues et on leur demande d’exécuter la liste de commande figurant entre[
et]
.
ask turtles [ ; liste de commande ]
who
).
ask turtle 2 [ set color blue ]
patches
ask patches ; Tous les patches [ set pcolor white ]
set
permet de donner une valeur à une variable. Chaque tortue a des variables propres (différentes pour chaque tortue) :xcor
etycor
ses coordonnées ;heading
orientation de la tortue. Lors de son prochain déplacement elle se déplace dans cette direction.size
la taille de la tortue.color
la couleur de la tortue.hidden?
la tortue est-elle visible ?who
le numéro de la tortue. Chaque tortue en possède un ce qui permet de la désigner.
random n
retourne une valeur entière dans l'intervalle [0..n[max-pxcor
etmax-pycor
fixe les coordonnées maximales duworld
.
Si vous regardez le résultat vous pouvez constater que cela n'est pas satisfaisant. Je vous propose de modifier le world
. Pour cela il faut cliquer sur le bouton Settings
.
Location of origin | Corner |
---|---|
max-pxcor | 150 |
max-pycor | 150 |
world wrap horizontally | yes |
world wrap horizontally | yes |
Patch size | 3 |
on ticks | yes |
Nous allons rendre maintenant nos tortues mobiles et pour cela on va définir la procédure go
. Elles vont se déplacer dans un premier temps de façon complément aléatoire.
to go ask turtles [ set heading heading + (random 30 - random 30) forward 1 ] end
set heading heading + (random 30 - random 30)
changement de direction aléatoire dans un cône de 30°forward 1
(fd 1
) avance d'une unité.
Vous pouvez maintenant tester avec le bouton go
. Il peut être utile d'éditer ce bouton et cocher la case forever
.
Je vous propose d'ajouter un switch
Trace?
qui va permettre de suivre la trajectoire de vos tortues.
to go ask turtles [ if Traces? ; Si le switch est on [ pen-down ; on baisse le crayon ] set heading heading + (random 30 - random 30) forward 1 ] end
Si vous exécutez ce programme, pensez à ralentir la vitesse avec le slider slower
.
Une nouvelle fois on s'adresse à toutes les tortues grâce à la commande ask [..]
et on a ajouté une instruction conditionnelle if
.
if condition
[
; liste des commandes effectuées quand condition est vraie
]
condition
représente une expression booléenne (
TRUE ou
FALSE) ou le résultat d'une fonction qui renvoie un booléen (
reporter@@ booléen).
Il est possible d'utiliser également un si alors sinon.
ifelse condition
[
; liste des commandes effectuées quand condition est vraie
]
[
; liste des commandes effectuées quand condition est fausse
]
Nos tortues doivent se comporter maintenant de façon plus sophistiquée et ne plus se déplacer au hasard. Nous allons
considérer qu'une tortue panique s'il y a au moins une autre tortue dans sa zone de confort. Nous allons commencer par écrire une fonction qui teste cela et renvoie true
si c'est le cas.
Il nous faut donc définir une fonction qui va retourner une valeur booléenne. NetLogo appelle désigne cela sous le nom de reporter
. Le squelette de base est le suivant :
to-report nomDeVotreFonction ; Traitement report resultat end
La zone de confort va être définie par un angle et un rayon que l'on doit pouvoir fixer au niveau de l'interface. Le Rayon
par un Input
des éléments d'interface et l'Angle
par un Slider
.
Notre fonction panique?
va s'écrire :
to-report panique? report count other turtles in-cone Rayon Angle > 0 end
report
retourne le résultat, c'est un booléen ici.count
Retourne le nombre d'agents de l'ensemble (agentset
) donnée.other
retourne un ensemble d'agents qui est le même que celui reçu en entrée mais ne contenant plus l'agent appelant.in-cone
permet de doter une tortue d'un « cône de vision » vers l'avant. Le cône est défini par les deux entrées le rayon et l'angle de vision, cette dernière valeur représentant l'ouverture du cône. L'angle de vision peut prendre des valeurs de 0 à 360 et est centré sur le direction courante de la tortue. Le résultat est un ensemble d'agents ne contenant que les agents se trouvant dans le cône et appartenant au même ensemble d'agents que l'agent appelant. L'agent appelant peut aussi en faire partie. La distance à un patch est mesurée à partir du centre de patch.
to setup clear-all ; On fait le ménage create-turtles Trouillardes ; Valeur obtenue par le slider correspondant ask turtles ; On s'adresse à toutes nos tortues [ set xcor random max-pxcor ; On fixe aléatoirement l'abscisse entre 0 et max-pxcor set ycor random max-pycor ; On fixe aléatoirement l'ordonnée entre 0 et max-pycor set heading random 360 ; On fixe aléatoirement l'orientation de la tortue set size 2 ; On fixe la taille set color green ; On fixe la couleur ] end to go ask turtles [ if Traces? [ pen-down ] ; La tortue doit-elle laisser une trace ifelse panique? ; La tortue panique t-elle ? [ set color red ; Oui elle bascule en rouge ] [ set color green ] set heading heading + (random Angle - random Angle) ; La tortue se déplace forward 1 ] end to-report panique? report count other turtles in-cone Rayon Angle > 0 end
Une tortue qui panique fait demi-tour et devient rouge, sinon elle avance. On définit deux procédures :
avancer
ausecours
to ausecours set color red set heading (heading - 180) forward 1 end to avancer set color green set heading heading + (random Angle - random Angle) ; La tortue se déplace forward 1 end
On va compter le nombre maximum de tortues paniquées à un temps t
. Pour cela on va déclarer une variable globale et l'initialiser à 0.
globals [ MaxPanique ] to setup ; ...... set MaxPanique 0 end
On crée ensuite au niveau de l'interface un monitor
que l'on associe à notre variable globale.
to go let m 0 ask turtles [ if Traces? [ pen-down ] ; La tortue doit-elle laisser une trace ifelse panique? ; La tortue panique t-elle ? [ ausecours ] [ avancer ] ] set m count turtles with [color = red] if m > MaxPanique [ set MaxPanique m] end
La procédure go
est modifiée en conséquence. On déclare une variable locale m
que l'on initialise à 0. Elle sert à stocker le nombre de tortue paniquée au temps t
et s'il est plus grand on modifie en conséquence MaxPanique
.
with
retourne un nouvel ensemble d'agents ne contenant que les agents de l'ensemble ayant satisfait à la condition donnée.
Pour terminer cette partie on trace la courbe d'évolution des tortues paniquées. Pour cela il faut modifier l'interface et le code (en vert).
globals [ MaxPanique ] to setup clear-all ; On fait le ménage create-turtles Trouillardes ; Valeur obtenue par le slider correspondant ask turtles ; On s'adresse à toutes nos tortues [ set xcor random max-pxcor ; On fixe aléatoirement l'abscisse entre 0 et max-pxcor set ycor random max-pycor ; On fixe aléatoirement l'ordonnée entre 0 et max-pycor set heading random 360 ; On fixe aléatoirement l'orientation de la tortue set size 2 ; On fixe la taille set color green ; On fixe la couleur ] set MaxPanique 0 reset-ticks end to go let m 0 ask turtles [ if Traces? [ pen-down ] ; La tortue doit-elle laisser une trace ifelse panique? ; La tortue panique t-elle ? [ ausecours ] [ avancer ] ] set m count turtles with [color = red] if m > MaxPanique [ set MaxPanique m] tick end to-report panique? report count other turtles in-cone Rayon Angle > 0 end to ausecours set color red set heading (heading - 180) forward 1 end to avancer set color green set heading heading + (random Angle - random Angle) ; La tortue se déplace forward 1 end
3.2 Une tortue qui n'a peur de rien
Ajoutons maintenant une tortue qui n'a peur de rien et qui avance droit devant quand il y en a une autre dans son champ de vision. Pour cela on va définir une variable propre à chaque tortue qui permet de savoir si elle est impressionnable?
ou pas. Pour créer cette variable on utilise :
turtles-own [ nonimpressionnable? ]
vous pouvez faire de même avec les patches
(patches-own [...]
). On va maintenant choisir une tortue de façon aléatoire qui n'a peur de rien.
to setup clear-all ; On fait le ménage create-turtles Trouillardes ; Valeur obtenue par le slider correspondant ask turtles ; On s'adresse à toutes nos tortues [ set xcor random max-pxcor ; On fixe aléatoirement l'abscisse entre 0 et max-pxcor set ycor random max-pycor ; On fixe aléatoirement l'ordonnée entre 0 et max-pycor set heading random 360 ; On fixe aléatoirement l'orientation de la tortue set size 2 ; On fixe la taille set color green ; On fixe la couleur set impressionnable? false ] ask one-of turtles [ set impressionnable? true ] set MaxPanique 0 reset-ticks end
one-of
retourne un agent pris au hasard dans l'ensemble d'agents.
Il reste à définir son comportement. Pour cela on va modifier notre procédure ausecours
à laquelle on va transmettre l'information si la tortue est impressionnable?
ou pas. L'appel se fait donc sous la forme ausecours impressionnable?
:
to go
let m 0
ask turtles
[
if Traces? [ pen-down ] ; La tortue doit-elle laisser une trace
ifelse panique? ; La tortue panique t-elle ?
[
ausecours nonimpressionnable?
]
[
avancer
]
]
set m count turtles with [color = red]
if m > MaxPanique [ set MaxPanique m ]
tick
end
Il faut modifier en conséquence la procédure ausecours
qui reçoit maintenant un argument. Les arguments formels sont mis entre crochets.
to ausecours [ courageuse? ]
set color red
if not courageuse?
[ set heading (heading - 180) ]
forward 1
end
3.3 Une nouvelle espèce de tortue
Nous allons maintenant ajouter d'autres tortues avec un comportement différent. Ces dernières sont affectueuses
et ont tendance à se diriger vers les tortues craintives
. Pour cela nous modifions notre code précédent en créant deux espèces de tortues : les affectueuses
et les craintives
. La création d'une espèce se fait grâce à :
breed [<espece> <individu>]
breed
est la commande qui permet la création d'une espèce. On précise comment on désigne uneespece
et un
individu@@ appartenant à cette espèce.
Cela nous donne donc :
breed [craintives craintive] breed [affectueuses affectueuse]
Les craintives
et les affectueuses
sont toujours bien sûr des turtles
. Néanmoins on utilise souvent cela pour s'adresser qu'à une partie des tortues.
ask craintives [ ... ]
Avant de définir le comportement de nos nouvelles tortues, on s'intéresse à adapter notre code afin de prendre en compte l'espèce craintives
.
globals [ MaxPanique ] breed [craintives craintive] breed [affectueuses affectueuse] craintives-own [ nonimpressionnable? ] to setup clear-all ; On fait le ménage create-craintives Trouillardes ; Valeur obtenue par le slider correspondant ask craintives ; On s'adresse aux craintives [ set xcor random max-pxcor ; On fixe aléatoirement l'abscisse entre 0 et max-pxcor set ycor random max-pycor ; On fixe aléatoirement l'ordonnée entre 0 et max-pycor set heading random 360 ; On fixe aléatoirement l'orientation de la tortue set size 2 ; On fixe la taille set color green ; On fixe la couleur set impressionnable? false ] ask one-of craintives [ set nonimpressionnable? true ] set MaxPanique 0 reset-ticks end to go let m 0 ask craintives [ if Traces? [ pen-down ] ; La tortue doit-elle laisser une trace ifelse panique? ; La tortue panique t-elle ? [ ausecours nonimpressionnable? ] [ avancer ] ] set m count craintives with [color = red] if m > MaxPanique [ set MaxPanique m ] tick end to-report panique? report count other turtles in-cone Rayon Angle > 0 end to ausecours [ courageuse? ] set color red if not courageuse? [ set heading (heading - 180) ] forward 1 end to avancer set color green set heading heading + (random Angle - random Angle) ; La tortue se déplace forward 1 end
On crée les tortues correspondant à une espèce par :
create-<especes> <nombre>
Nous ajoutons ensuite nos tortues affectueuses
qui sont au nombre de Calines
défini par un slider
.
Cela nous conduit à modifier la procédure setup
dans laquelle on crée et initialise les craintives
et les affectueuses
. On regroupe des traitements identiques (position, couleur ...) dans une même procédure initCaracteristique
. Dans l'extrait de code ci-dessous on pourra remarquer que dans un même temps on créée les affectueuses
et on les initialise.
to setup clear-all ; On fait le ménage create-craintives Trouillardes ; Valeur obtenue par le slider correspondant ask craintives ; On s'adresse à toutes les craintives [ initCaracteristique green set nonimpressionnable? false ] ask one-of craintives [ set nonimpressionnable? true ] create-affectueuses Calines ; Valeur obtenue par le slider correspondant [ initCaracteristique blue ] set MaxPanique 0 reset-ticks end to initCaracteristique [c] set xcor random max-pxcor ; On fixe aléatoirement l'abscisse entre 0 et max-pxcor set ycor random max-pycor ; On fixe aléatoirement l'ordonnée entre 0 et max-pycor set heading random 360 ; On fixe aléatoirement l'orientation de la tortue set size 2 ; On fixe la taille set color c ; On fixe la couleur end
La mobilité de nos tortues affectueuses
va être aléatoire si elles ne perçoivent pas de tortues craintives
dans leur voisinage sinon elles vont tenter de se rapprocher de la plus voisine.
to caliner let copine craintives in-cone (Rayon + 1) Angle ifelse any? copine [ face min-one-of copine [distance myself] ] [ set heading heading + (random Angle - random Angle) ; La tortue se déplace ] forward 1 end
On réutilise le cône de vision et copine
contient l'ensemble des craintives
visibles en fonction de ce cône. On teste si la liste copine
est vide avec any?
.
any?
teste si la liste d'agents est vide (TRUE/FALSE
).
Si la liste n'est pas vide la tortue s'oriente vers la plus proche et avance.
face <uneTortue>
modifie la direction de la tortue de façon à ce qu'elle pointe versuneTortue
.min-one-of <ensembleDAgents> [<reporter>]
retourne l'agent de l'ensemble d'agent agentset qui a la plus petite valeur pour le reporter donné (fonction retournant une valeur). S'il y a égalité, cette commande retourne un agent pris au hasard parmi ceux ayant cette plus petite valeur.distance <agent>
Retourne la distance qu'il y a entre l'agent appelant et la tortue ou le patch spécifié paragent
.myself
signifie « la tortue ou le patch qui m'a demandé de faire ce que je suis justement en train de faire » (self
correspond à « moi »).
globals [ MaxPanique ] breed [craintives craintive] breed [affectueuses affectueuse] craintives-own [ nonimpressionnable? ] to setup clear-all ; On fait le ménage create-craintives Trouillardes ; Valeur obtenue par le slider correspondant ask craintives ; On s'adresse à toutes les craintives [ initCaracteristique green set nonimpressionnable? false ] ask one-of craintives [ set nonimpressionnable? true ] create-affectueuses Calines ; Valeur obtenue par le slider correspondant [ initCaracteristique blue ] set MaxPanique 0 reset-ticks end to go let m 0 ask craintives [ if Traces? [ pen-down ] ; La tortue doit-elle laisser une trace ifelse panique? ; La tortue panique t-elle ? [ ausecours nonimpressionnable? ] [ avancer ] ] ask affectueuses [ if Traces? [ pen-down ] ; La tortue doit-elle laisser une trace caliner ] set m count craintives with [color = red] if m > MaxPanique [ set MaxPanique m ] tick end to-report panique? report count other turtles in-cone Rayon Angle > 0 end to ausecours [ courageuse? ] set color red if not courageuse? [ set heading (heading - 180) ] forward 1 end to avancer set color green set heading heading + (random Angle - random Angle) ; La tortue se déplace forward 1 end to caliner let copine craintives in-cone (Rayon + 1) Angle ifelse any? copine [ face min-one-of copine [distance myself] ] [ set heading heading + (random Angle - random Angle) ; La tortue se déplace ] forward 1 end to initCaracteristique [c] set xcor random max-pxcor ; On fixe aléatoirement l'abscisse entre 0 et max-pxcor set ycor random max-pycor ; On fixe aléatoirement l'ordonnée entre 0 et max-pycor set heading random 360 ; On fixe aléatoirement l'orientation de la tortue set size 2 ; On fixe la taille set color c ; On fixe la couleur end
4. Adaptation du problème : proies prédateurs
Vous pouvez maintenant étendre le problème au problème de proies/prédateurs.