Introduction à la Programmation Orientée Agent


proposé par François Suro - Janvier 2018

adapé de contenus proposé par Jacques Ferber

Netlogo se trouve à l'adresse: ccl.northwestern.edu/netlogo. Le manuel de l'utilisateur se trouve à l'adresse: http://ccl.northwestern.edu/netlogo/docs/

Si vous êtes sous Linux des salles machines de la fac de Montpellier II, il faut lancer NetLogo à partir du menu Education>Netlogo sous Xubuntu

Pour avoir des exemples de modèles (c'est à dire, dans le jargon NetLogo, les projets NetLogo existants), il suffit d'aller dans Fichier>Bibliothèques de modèles (ou ctrl + M).

1. Primitives NetLogo

Le lien suivant vous amènera au dictionaire de NetLogo (aussi disponible par Help>NetLogo dictionary).
Le dictionaire contient toutes les primitives NetLogo, il est très facile d'obtenir toutes les informations dont vous aurez besoin, soit par l'index , soit par ctrl + F.

Quelques éléments pour démarrer :

1.1. Déclarations du modèle

En tete du fichier, hors de toute procédure

Pour déclarer des variables globales:
globals[variable1 variable2 ....]
Les turtles sont les agents de base de NetLogo, le nom de la superclass des agents. il est possible de déclarer des sous classes de turtles, afin par exemple de leur donner des attributs différents. Ces sous classes sont apellées des Breeds, et se déclarent avec le nom de la breed au pluriel suivi du nom au singulier (ex: wolves wolf) :
breed [humans human]
Les agents (turtles et breeds) ainsi que les patches peuvent posséder des attributs qui se déclarent comme il suit :
humans-own [fear desire]
patches-own [grass]

1.2. Procédure

Pour déclarer une procédure (fonction NetLogo):
to nomProcedure
;; du code end
Procédure avec des paramètres (ici stock la somme des paramètres dans une variable locale):
to nomProcedure [param1 param2]
let somme param1 + param2 end
Procédure avec valeure de retour (ici retourne la somme des paramètres):
to-report nomProcedure [param1 param2]
report param1 + param2 end

1.3. Variables et attributs

Pour déclarer une varibale locale (et initialiser):
let variable valeureInitialisation
Modifier une variable ou attribut (ici, incrémenter):
set variable variable + 1

1.4. Structures de controle

If (si le patch est jaune, exécuter la procédure pick-up-chip):
if pcolor = yellow
[pick-up-chip]
If Else (si le patch est noir, exécuter la procédure put-down-chip puis wiggle, sinon exécuter la procédure wiggle):
ifelse pcolor = black
[put-down-chip wiggle]
[wiggle]

Demander a un agent ou un patche d'éxécuter des procédures (demande au patch sur lequel l'agent se trouve de décrémenter son attribut grass):

ask patch-here [set grass grass - 1]

1.5. Primitives agents

Tourner à droite (Right Turn), tourner à gauche (Left Turn), avancer (ForwarD):
rt angleEnDegrés
lt angleEnDegrés fd distanceNombreRéel
S'orienter vers un agent ou un patch (s'orienter vers l'agent contenu dans la variable agentCible, s'orienter vers le patche aux coordonées 0 0):
face agentCible
face patch-at 0 0

2. Prise en main

Utilisez le programme simple_aleatoire1 qui permet de démarrer. (attention, il faut que vous téléchargiez ce fichier (click droit de souris > save) et non que vous fassiez un copier-coller avec ce programme).

3. Construction d'une termitière

Utilisez le programme Termites-base qui permet de démarrer. On souhaite que les agents, des termites, constuisent une termitière en regroupant des brindilles ensemble (chips en anglais, symbolisé par la couleur jaune sur un patch). Les termites ont une perception très limité, pour représenter cela on considére qu'elle ne peuvent percevoir que le patch sur lequel elle sont situés.

L'algorithme est le suivant:

Note: tous les agents de NetLogo possèdent un attribut de couleur:

color

L'attribut de couleur des patches:

pcolor

Les agents possèdent aussi l'attribut pcolor comme raccourcit vers la couleur du patch sur lequel ils se situent. Ceci permet à l'agent d'utiliser la couleur du patch sans avoir recours à la fonction ask:

set pcolor green

3b. (Optionel) Tri collectif par des termites

Selon le temps à votre disposition et votre préférence, vous pouvez faire cet exercice qui explore un peu plus les algorithmes agent ou passer directement à la partie 4 qui se concentre sur l'aplication de la programation agent aux simulations.

Supposons maintenant qu'il existe deux types de brindilles (chips en anglais), des jaunes (celles qui sont déjà intégrées au programme) et des vertes. Modifier le programme Termites pour qu'il s'appelle maintenant "tri collectif", et faites en sorte que quand une termite porte une brindille jaune, elle l'ajoute à un tas de brindilles jaunes, et si elle porte une brindille verte elle l'ajoute à un tas de brindilles vertes.

Dans ce cas, vous verrez la construction de deux tas: le tas des "jaunes" et le tas des "vertes".. Vous avez ainsi réalisé un programme de tri distribué...

Attention: il y a un petit "truc" pour faire en sorte que les tas ne soient pas trop mélangés....

4. Simulation de populations

Nous allons essayer de modéliser un système de gestion de ressources en NetLogo.

4.1. Faire évoluer l'environnement

a) Dans un premier temps on va faire "pousser" des ressources dans un environnement.. Pour cela on va supposer que les patches peuvent faire pousser de l'herbe...

On supposera que chaque parcelle de terrain (représentée par un patch) peut être soit pleine d'herbe (verte), soit déserte (noir). On va supposer que l'herbe repousse naturellement chaque patch disposant de sa propre vitesse de croissance.

Dans un premier temps, on suppose que les patches n'ont que deux états: l'état 'plein d'herbes' et l'état 'désert'. Mais le temps de passage de l'état désert à l'état 'herbe' dépend d'un compteur de temps 'cpt-temps', propre à chaque patch, qui indiquera le temps qu'il lui reste à attendre avant de passer de l'état 'désert' à l'état 'herbeux' et inversement.

Ce compteur est initialisé à une valeur 'cpt-temps-init' laquelle est définie de manière aléatoire pour chaque patch par une valeur entre 1 et 'temps-croissance-max' qui sera associé à un slider.

Le principe est le suivant:

Implémentez de tels patches

Note: dans la version 5 de NetLogo il est important de mettre une instruction 'clear-all' au début et un 'reset-ticks' à la fin de votre procédure d'initialisation (setup). Cela donne donc ceci:

to setup
 clear-all
 ... ;; initialisation
 ...;; du programme
 reset-ticks
end
to go
 ..;; la procedure qui sera appelee a céquà cycle...
 tick
end

b) On supposera maintenant qu'il n'y a plus deux états possibles, mais une variable continue qui caractérise la quantité de plantes qu'il y a sur un patch (attribut taille-plante). Cet attribut sera incrémenté à chaque fois que le compteur cpt-temps revient à zéro.

On attribuera une valeur maximum pour la taille des plantes (taille-plante-max) qui sera associée à un slider (par exemple entre 50 et 200)

Pour visualiser la taille des plantes, on pourra utiliser la fonction scale-color de NetLogo qui retourne une couleur proportionnelle à une valeur (aller regarder sa définition dans le manuel de programmation de NetLogo). Par exemple, pour mettre la couleur d'un patche en correspondance avec la valeur de l'attribut 'taille-plante', quelque chose comme cela devrait faire l'affaire (Attention: c'est juste une proposition: essayez avec d'autres valeurs que 70 et faites en sorte ensuite que le gradient de couleur soit relié à la taille maximale des plantes (taille-plante-max) tout en conservant une belle couleur verte sur les patches.

set pcolor scale-color green taille-plante 0 70

Visualisez ainsi des patches qui poussent et croissent à partir de valeurs aléatoires initiales. On supposera que lorsque la valeur de l'attribut taille-plante est à taille-plante-max le patch voit la taille des plante décroire, et quand elle arrive à zéro (ou négatif), le patch devient désert et il recontinue sa croissance ensuite.

4.2. Créer des consommateurs de ressources

On fait maintenant venir des vaches qui viennent brouter l'herbe. On suppose qu'une vache prend un peu de la valeur de taille-plante, c'est à dire qu'elle diminue la quantité d'herbe qui se trouve sur un patche.. Chaque fois qu'une vache tombe sur un patche vert, elle diminue sa valeur taille-plante d'une valeur consommation-vache qui est définie de manière globale (c'est un paramètre auquel on associe un slider). Evidemment l'herbe repousse ensuite.

Faites en sorte que les vaches se déplacent aléatoirement et broutent.. Voyez ce qui se passe en fonction des paramètres temps-croissance et consommation-vache.. Qui va gagner de l'herbe ou des vaches?

Visualiser la quantité totale de vaches et d'herbe à l'aide d'un moniteur d'interface de type 'plot'.

Note: pour visualiser une courbe sous NetLogo : à la fin de la procédure to go, ajouter la ligne suivante:

 update-plots

Et créez un "plot" (comme on crée un bouton) et dans le pen (le crayon) "default" (dont vous pouvez changer le nom en "herbe" par exemple), écrivez l'expression suivante

 sum [taille-plante] of patches

Cela signifie qu'à chaque tour, il affiche dans le "plot", pour la courbe "herbe", la totalité d'herbe qui existe dans votre terrain..

Pour plus d'informations sur la manière de visualiser une courbe sous NetLogo, voir la documentation de l'interface de NetLogo.

4.3. Troupeaux de vaches

Faites en sorte que vos vaches se déplacent en troupeau. Faites un "taureau" et un ensemble de vaches qui le suivent.

Une vache avance de manière aléatoire jusqu'à ce qu'elle rencontre un taureau située à une certaine distance de perception (paramètre qui peut être mise sous la forme d'un slider) qu'elle se mettra à suivre.

En même temps qu'elles avencent et suivent le taureau, elles se repaissent de l'herbe qu'elles croisent. Voyez l'évolution de votre terrain en fonction du déplacement des vaches.

Note: in-radius n retourne un agentset qui contient tous les agents situés à une distance de n de la tortue (ou patch) courant. Cela s'utilise avec un filtre:

turtles in-radius n

retourne toutes les tortues à une distance n

taureaux in-radius n

retourne touts les taureaux à une distance n. Pour n'en retourner qu'un, faire:

one-of taureaux in-radius n

s'il n'y en a pas, cela retourne nobody.. Pour aller vers une chose on peut écrire set heading towards xx est l'entité (tortue ou patche)

4.4. Prédateurs

a) On crée maintenant un ensemble de prédateurs, des lions, qui viennent manger les vaches (ils ne mangent pas les taureaux!!). Ces lions avancent de manière aléatoire, et dès qu'ils repèrent une vache dans un certain rayon de perception (de 3 à 20 par exemple, mettre cela aussi sous la forme d'un paramètre et d'un slider), ils lui foncent dessus, et s'il se trouve sur le même patche que la vache, il la mange (En NetLogo, le code other <breed>-here retourne toutes les tortues de type <breed> qui se trouvent sur le même patch, la tortue courante ayant été omise. Attention, même s'il y a plusieurs vaches sur le même patch, il ne doit en manger qu'une!! Regardez dans la doc la définition de other et de turtles-here).

Note: La primitive pour tuer un agent est 'die'. Si l'agent se "tue" lui-même, il suffit de faire

die 

Si on demande à un autre agent de se tuer, on peut le faire en utilisant la commande:

ask <agent> [die] 

Pour retourner la distance entre l'agent courant et un agent cible:

distance agentCible 

Récupérer un agent parmis un agentSet dont une charactéristique est minimum (ici, retourne l'agent parmis tous les agents de la simulation dont l'identifiant (commande who) est le plus petit):

min-one-of turtles [who] 

Regardez ce qui se passe en fonction du nombre initial de lions et de vaches.

b) On donne maintenant des capacités de reproduction aux lions et aux vaches. On suppose d'abord qu'ils disposent tous les deux d'une variable énergie qui est décrémentée à chaque tick (à chaque pas de temps). Cette valeur est incrémentée lorsque les vaches mangent l'herbe (elles prennent un certain quota d'énergie à chaque fois qu'elles prennent de l'herbe) et lorsque les lions mangent les vaches (les lions prennent un certain quota d'énergie à chaque fois qu'ils mangent une vache). Ces quotas d'énergie correspondent à des paramètres gain-brouter pour les vaches et gain-devorer pour les lions. Leur attribut énergétique s'exprime alors sous la forme:

 set energie energie + gain-brouter 

pour la vache chaque fois qu'elle broute et idem pour le lion à chaque fois qu'il mange une vache (avec la valeur gain-devorer dans ce cas). On suppose qu'ils se reproduisent de manière aléatoire, ce nombre aléatoire étant pris dans l'étendue 0..reproduction-vaches pour la reproduction des vaches (et de la même manière pour les lions). On suppose aussi que la valeur énergétique d'un animal est divisée par deux lorsqu'il se reproduit.

Note: En NetLogo, la commande

hatch 1 [<code exécuté par l'enfant à l'initialisation>]

permet de créer une copie de la tortue courante, l'enfant se trouvant au même endroit que le parent.

Jouez un peu avec les variables et observez l'évolution de votre monde dans lequel de l'herbe pousse, des vaches et des lions évoluent... A l'école des dieux, savez vous créer un monde qui perdure?