• Aucun résultat trouvé

La plateforme de simulation Repast Simphony

Nous avons choisi la plateforme de la simulation Repast pour les raisons invoquées dans le chapitre 2. Dans ce qui suit, nous en donnons les éléments de base nécessaires à la compré-hension des développements que nous avons menés dans le cadre de ce travail. Trois notions importantes dans Repast Simphony sont : les contextes, les projections et comme tout simula-teur, l’ordonnancement.

FIGURE3.5 – Le module de planification

3.3.1 Les contextes

Les contextes sont les concepts de base dans Repast Simphony. Un contexte fournit une structure de données pour organiser les agents autant pour la modélisation que pour l’implé-mentation. Concrètement, un contexte est une collection d’agents, mais un peu plus riche qu’une simple collection. Les contextes dans Repast sont hiérarchiquement imbriqués, chacun étant un conteneur de composants du modèle. Les composants du modèle peuvent être des simples ob-jets POJO12, y compris d’autres contextes, mais on s’attend souvent à ce qu’ils soient des objets représentant des agents ayant un comportement. Chaque composant du modèle peut être présent dans de nombreux contextes selon les besoins du concepteur. Un composant du modèle, qui est présent dans un contexte, est également présent dans tous les contextes parents de ce contexte (l’inverse n’est évidemment pas vrai).

L’un des intérêts principaux des contextes est qu’ils servent comme support à des projections (voir plus bas). Les projections dans Repast sont des relations définies sur les membres d’un contexte. Par exemple, la projection Network stocke une relation du réseau ou d’un graphe entre les membres de son contexte. Les membres de ce contexte peuvent alors savoir à qui ils sont liés et qui sont liés à eux. De même, la projection Grid stocke un ensemble de coordonnées cartésiennes pour chaque membre du contexte. Les membres de ce contexte peuvent savoir où ils se trouvent dans la grille.

Les contextes sont également en charge des couches de données. Les couches de données représentent les données numériques qui peuvent être accessibles en utilisant un ensemble de coordonnées. Les couches de données permettent aux concepteurs de modèles de fournir des

valeurs numériques avec lesquels leurs agents peuvent interagir.

3.3.2 Les projections

Alors que les contextes créent une collection pour organiser les agents, les projections im-posent une structure sur ces agents. En utilisant les seuls contextes, on ne peut écrire un modèle qui fournit plus qu’un simple conteneur pour les agents. Les projections permettent de créer une structure qui définit les relations, qu’elles soient spatiales, sémantiques, etc. Une projection est attachée à un contexte particulier et s’applique à tous les agents dans ce contexte. Un point important est à signaler ici : un objet doit exister dans un contexte avant d’être utilisé dans une projection. On peut appliquer autant de projections qu’on désire à un même contexte. On peut donc avoir un contexte qui contient une grille et deux espaces géographiques (deux manières de représenter un réseau de transport par exemple). Les agents peuvent obtenir une référence à diverses projections à travers le contexte auquel ils appartiennent. Un agent peut faire ce qui suit (this se réfère à l’agent) :

Cette projection ne serait pas utile à moins qu’on « caste » la projection à une représentation plus spécifique (un Network par exemple).

En général, les projections sont créés en utilisant le mécanisme de trouver la Factory ainsi. — Trouver la Factory

— Utiliser la Factory pour créer la projection Par exemple, pour créer une grille :

Chaque Factory crée une projection d’un type spécifique et nécessite le contexte auquel la projection est associée et le nom des projections ainsi que des arguments supplémentaires notamment pour le type de projection. Ces arguments supplémentaires ne sont pas définis ci-dessus (le paramètre params).

3.3.3 L’ordonnancement

L’ordonnancement est un composant clé de toute simulation. Il définit la manière avec la-quelle les actions des agents sont exécutés pendant la simulation. Il y a trois manières de tra-vailler avec l’ordonnanceur de Repast.

Ordonnancer directement une action Pour ordonnancer directement une action dans Re-past, on récupère une référence vers un Schedule et on l’informe du moment où l’action doit être exécutée. Ci-après un exemple d’ajout d’une action au Schedule.

Ordonnancer avec les annotations

Les annotations sont des métadonnées qui peuvent être associées aux classes, méthodes ou attributs qui sont disponibles pendant l’exécution pour donner au système plus d’informations. Pour Repast, les annotations sont utilisées entre autres pour associer des informations d’ordon-nancement aux méthodes.

Ici la méthode move est ordonnancée à partir du tick 1, elle s’exécute tous les deux ticks, et a une priorité de 2. Cela signifie que si une autre action de priorité inférieur (1 par exemple) est ordonnancée, move sera exécutée avant elle. L’usage des annotations est le plus simple lorsque les paramètres d’ordonnancement sont connues lors de la compilation. Les arguments des annotations sont similaires aux propriétés d’un objet ScheduleParameters. La plupart du temps, les objets avec annotations sont automatiquement ajoutés au schedule.

Ordonnancer avec le Watcher

Les Watchers ou observateurs sont conçus pour être utilisés pour l’ordonnancement dyna-mique où un workflow typique est bien compris par le concepteur du modèle. Un observateur permet à un agent d’être notifié d’un changement d’état dans un autre agent et planifier un événement de se produire à la suite. Le watcher est mis en place en utilisant une annotation. Mais au lieu d’utiliser les temps statiques pour les paramètres de planification, l’utilisateur spé-cifie une requête définissant les agents à observer et une requête définissant une condition de déclenchement qui doivent être remplies pour exécuter l’action.

L’annotation @Watch avant la méthode indique à Repast Simphony d’observer les autres objets pour ordonnancer la méthode move(). Ici, l’agent voyageur voudrait mettre à jour sa position à chaque fois que son bus change de position. Le premier paramètre de l’annotation est le watcheeClassName. Il définit le type d’agents que cet agent va surveiller. Le second argument, watcheeFieldName, définit l’attribut à surveiller. Cela signifie qu’il y a une variable dans la classe busAgent, dont nous voulons surveiller les changements. Quand elle change, cet agent sera notifié. L’argument whenToTrigger spécifie s’il faut exécuter l’action immédiatement (avant que les autres actions planifiées à cette instant ne soient exécutées) ou d’attendre jusqu’au prochain tick. Enfin, le scheduleTriggerPriority permet de définir l’ordre d’exécution de cette action.