CAHIER DES CHARGES ET HYPOTHESES
Pour répondre au besoin de modularité et faciliter la mise en œuvre de modèles, qu’ils soient anciens ou nouveaux, l’architecture de la plateforme devra être générale. Sa structure devra être la plus simple possible pour que la mise en œuvre de modèles se fasse sans un gros travail d’écriture, même si elle nécessite quelques connaissances en informatique.
Le fonctionnement de la plateforme ne doit pas induire de comportement particulier ni d’exécution particulière, tout doit dépendre du modèle. L’architecture devra ainsi éviter des biais, dans l’exécution ou dans l’écriture du modèle. Les limites rencontrées doivent être le fait du modèle et non de l’environnement logiciel, c’est-à-dire que le fonctionnement du modèle ne doit pas être contraint par la plateforme, que ce soit en termes de temps, d’espace, ou autre. Le temps et l’espace seront donc des propriétés des modèles et non de la plateforme.
Nous avons vu lors de la description des systèmes biologiques qu’ils sont par nature multi-échelles. Modéliser une population cellulaire doit pouvoir se faire à plusieurs niveaux. Nous nous fixons donc comme objectif de pouvoir utiliser des modèles multi-échelles, ou à tout le moins de faire du multi-échelle, en faisant cohabiter des modèles différents pour les différentes échelles.
Notre attention se portant principalement sur les populations cellulaires, ce sera donc l’objet des modèles individu-centrés que nous étudierons. Nous choisissons de modéliser les individus, et par conséquent les cellules, par deux objets qui décriront d’une part les processus, et d’autre part les caractéristiques. Il n’y aura ainsi pas de classe spécifique pour modéliser les cellules biologiques, mais deux classes, une structure qui est manipulée par un modèle.
Les différents modèles qui auront été implémentés seront stockés et disponibles dans une bibliothèque de modèles qui permettra leur réutilisation ultérieure, soit pour combiner leurs approches, soit pour les présenter facilement à titre d’illustration par exemple.
ARCHITECTURE
Les différents niveaux de modélisation seront associés à des classes. Le niveau microscopique sera adressé par la classe CellModel, le niveau macroscopique sera adressé par la classe Population. Produire un modèle individu-centré se fera en dérivant la classe CellModel, alors que produire un modèle à population se fera en dérivant la classe Population. Le niveau de modélisation mésoscopique se fera en définissant une population associée à un modèle qui représentera un groupe d’individus et non plus un seul individu.
Cette architecture est présentée à la Figure IV.1.
L’élément central de l’architecture sera la classe Population. C’est à son niveau que se fera la gestion des individus et leurs interactions avec leur environnement. Ces interactions seront définies au niveau du CellModel, mais le passage des informations entre les instances de CellModel et l’environnement sera effectué par la Population. Elle permettra également de propager entre les individus les informations de mise à jour liées aux relations interindividuelles.
De fait, c’est la définition de la population qui indiquera le type de modélisation (discrète, continue, contrôlée par horloge…). La Population manipule un ensemble de CellModel. Elle peut être homogène et présenter plusieurs instances d’un même CellModel, ou hétérogène avec plusieurs instances de différents CellModel.
Un CellModel correspond à un type de cellule et ne manipule donc qu’une seule structure. Chaque individu est une instance d’un CellModel qui manipule une instance d’une CellStructure.
Les attributs de base d’une CellStructure, présents dans la classe abstraite CellStructure, correspondent à ses coordonnées cartésiennes, _IdX et _IdY). Comme il n’y a pas d’hypothèse sur l’espace dans la plateforme, ces attributs sont valables que l’on considère un espace continu ou discret, à une ou deux dimensions.
La démarche pour implémenter un nouveau modèle consiste à créer les classes dérivées des classes abstraites CellStructure, qui porte les attributs représentant les caractéristiques biologiques modélisées, et CellModel qui présente les méthodes représentant les processus biologiques d’intérêt (le cycle cellulaire en particulier pour un modèle individu-centré de cellule). S’il est besoin d’un environnement particulier, il sera décrit dans la classe Environment et présentera des attributs qui représenteront toutes les caractéristiques d’intérêt pour le modèle, comme par exemple une information de température, la quantité d’un nutriment disponible, etc… Les attributs de cette classe peuvent être consultés ou modifiés par les CellModel en passant par la Population.
La classe CellModel présente une méthode abstraite, « Change () » et une méthode concrète ApplyChange ()». Cette dernière n’a d’intérêt que pour les modèles individu-centrés. Elle applique à l’individu le nouvel état qui est calculé par la méthode « Change () », elle est donc indépendante du modèle, à la différence de la méthode « Change () » qui doit être rendue concrète dans la classe concrète CellModel. C’est donc à la définition de cette dernière en dérivant la classe CellModel que sera défini le contenu de la méthode « Change () ».
En résumé, cette architecture permet la manipulation concrète au niveau d’une classe abstraite, la CellStructure dérivée de CellStructure est manipulée par la méthode « Change () » du CellModel dérivé de CellModel.
On donnera le choix à l’utilisateur de spécifier en début d’exécution les conditions initiales ou de laisser calculer une configuration aléatoire, par exemple, pour jouer un modèle de population bactérienne, soit l’utilisateur fournit une population donnée, soit la plateforme en génère une aléatoirement.
L’environnement pris en compte dans la classe Environment est actuellement simple, mais il sera à terme capable de proposer des listes de paramètres chimiques, par exemple des listes de nutriments et leur quantité respective, une liste de toxiques, etc… et des paramètres physiques comme la température, la pression, etc… Chacun de ces éléments doit pouvoir être rendu disponible et consulté par les individus.
APPLICATIONS : MODELES ET VALIDATION DE LA PLATEFORME
L’issue de notre état de l’art, nous avons choisi de nous orienter vers l’utilisation des automates cellulaires comme support de modèles individu-centrés. Aussi, nous nous sommes intéressés à implémenter dans la plateforme des automates cellulaires bien connus dans la littérature, le Jeu de la Vie et Wireworld.
Nous avons également choisi d’expérimenter l’implémentation d’un modèle d’homéostasie*, Daisyworld, sous la forme d’automates cellulaires en considérant d’abord une version simplifiée avec un système isolé, puis la version classique avec un système fermé.
Nous orienter vers les automates cellulaires pour valider le comportement de la plateforme et mettre en œuvre notre modèle de cellules biologiques nous a imposé certaines adaptations ou certaines précisions sur elle.
ADAPTATIONS DE LA PLATEFORME LIEES A L’AUTOMATE CELLULAIRE
La définition d’un automate cellulaire donne une fonction de transition qui régit le devenir de l’état d’une cellule dans le temps à travers l’interaction avec les cellules considérées dans son voisinage. L’utilisation de la plateforme pour mettre en œuvre ces automates cellulaires passe donc par la définition de leur fonction de transition au sein de la méthode Change() » de la classe CellModel développée pour chacun d’eux.
Avec la fonction de transition, il faut définir l’ensemble des états que peut prendre chaque cellule, ces états seront représentés par l’attribut _state de la classe CellStructure.
La fonction de transition d’un automate cellulaire permet de calculer l’état d’une cellule à un temps t+1 à partir de son état à un temps t et de l’état de ses cellules voisines. Il nous faut donc développer une classe qui contient la méthode de calcul du voisinage.
C’est également à son niveau que se décide la topologie de l’espace (1D, 2D, …), si l’espace est continu ou discret, et dans ce dernier cas, la forme du maillage. Nous avons implémenté le calcul des voisinages de Von Neumann et de Moore, avec pour ce dernier plusieurs rayons possibles (Figure IV.2). Nous considérons qu’un voisinage de Moore de rayon infini correspond à un voisinage global, c’est-à-dire à l’utilisation de la matrice entière comme système de voisinage pour chaque cellule.
Cette classe est sollicitée lors de l’initialisation de l’automate cellulaire et à chaque fois que les voisins ont besoin d’être recalculés, par exemple si l’on considère que les individus se déplacent.
Nous avons implémenté cinq processus de mise à jour du modèle. Ils constituent des méthodes de la classe Population.
L’homéostasie est la capacité d’un système à maintenir son équilibre de fonctionnement en dépit de contraintes extérieures UpdateAll » décrit une mise à jour synchrone du système. Tous les éléments sont au même pas de temps. Cette méthode appelle la méthode « Change » de chaque CellModel à chaque pas de temps de la simulation, et appelle la méthode « ApplyChange () » de CellModel à la fin de chaque pas de temps. « Change () « calcule l’état à t+1 en à partir de l’état à t et en fonction des voisins, et tous sont encore à l’état t. L’état à t+1 est appliqué à tous les individus en même temps. Avec cette méthode, les cellules sont synchrones entre les pas de temps et dans le pas de temps. Ce processus a été implémenté de deux façons, la première,
• UpdateAll () », réalisant la mise à jour des cellules dans leur ordre lexicographique (i.e. dans l’ordre de leurs coordonnées dans l’espace), la seconde, « UpdateAllRand () », procédant à la mise à jour des cellules dans un ordre aléatoire.
• UpdateAllAsynchrone » décrit une mise à jour asynchrone-synchrone du système. Au cours d’un pas de temps de la simulation, l’état à t+1 d’un CellModel est calculé par appel de sa méthode « Change () «. Ce nouvel état est aussitôt appliqué par appel de la méthode
• ApplyChange () ». Ainsi, le calcul de l’état d’une cellule prend en compte son état à l’instant t, et l’état de ses voisines. Mais comme certaines ont été mises à jour, certaines sont à l’état t, d’autres sont à l’état t+1. Le pas de temps est terminé lorsque toutes les cellules ont été mises à jour et que toutes sont à l’état t+1. En résumé, les cellules sont synchrones entre les pas de temps, mais asynchrones au cours d’un pas de temps, la resynchronisation ayant lieu à la fin de chaque pas de temps. Ce processus a également été implémenté sous deux formes, « UpdateAllAsynchrone () » réalisant la mise à jour des cellules dans leur ordre lexicographique, et « UpdateAllAsynchroneRand () » procédant à la mise à jour des cellules dans un ordre aléatoire. « UpdateAllAsynchroneOne () » reprend le principe de la méthode UpdateAllAsynchroneRand () » mais avec la disparition de la notion de pas de temps de la simulation. Ou plus exactement, le calcul de l’état à t+1 et l’application de ce nouvel état à une cellule compte pour un pas de temps. De fait, avec un ordre de mise à jour aléatoire des cellules, certaines seront mises à jour pour la première fois alors que certaines de leurs voisines auront déjà subies plusieurs mise à jour, les cellules sont toutes désynchronisées et le processus est totalement asynchrone. Ce processus utilise forcément un ordre de mise à jour des cellules aléatoire et n’a donc été implémenté que sous cette seule forme.
Pour les méthodes qui permettent la mise à jour des cellules dans un ordre aléatoire, nous avons fait l’essai de mettre calculer l’ordre de mise à jour une fois au début de l’exécution, ou chaque itération. Les résultats de ces deux façons de procéder sont comparés (voir le paragraphe V.2, page 167).
JEU DE LA VIE
SPECIFICATIONS
Le Jeu de la Vie a été proposé par John Conway en 1970 sous le nom Game of Life. Il s’agit de l’un des automates cellulaires les plus documentés depuis sa popularisation par Martin Gardner qui le présente dans son article «The fantastic combinations of John Conway’s new solitaire game « life »» (Gardner, 1970 [130]).
Il s’agit d’un automate cellulaire déterministe et homogène, synchrone, basé sur un maillage régulier exploitant un voisinage de Moore.
Les cellules peuvent présenter deux états :
• active (ou vivante) ;
• inerte (ou morte).
Le comportement de cet automate cellulaire est dicté par une fonction de transition comprenant trois règles :
• Une cellule morte devient vivante si deux ou trois cellules sont vivantes dans le voisinage, elle reste morte sinon ;
• Une cellule vivante meurt d’isolement si elle a au plus une cellule vivante dans le voisinage ;
• Une cellule vivante meurt par surpopulation si elle a dans son voisinage au moins quatre cellules vivantes.
Cette fonction peut aussi s’écrire de manière suivante :
• Une cellule devient ou reste active si elle a dans son voisinage deux ou trois cellules actives, dans tous les autres cas, elle devient ou reste inactive.
Cette fonction simple permet de générer des comportements relativement complexes. Des conditions initiales aléatoires peuvent faire apparaître plusieurs structures remarquables regroupées dans trois classes : oscillateurs, stables et planeurs (ou gliders).
Les oscillateurs sont des structures qui possèdent plusieurs formes et passent de l’une à l’autre régulièrement avec une périodicité caractéristique. L’oscillateur le plus simple, la structure en haut à gauche dans la Figure IV.3, est constitué d’un alignement de trois cellules actives et bascule entre chaque forme à chaque pas de temps.
Les formes stables gardent la même structure dans le temps. La plus petite forme stable, représentée en bas à droite dans la Figure IV.3, est constituée d’un carré de quatre cellules actives.
Figure IV.3 : Évolution sur 5 pas de temps de figures simples observées dans le Jeu de la Vie. L’oscillateur, en haut à gauche, alterne ses deux formes à chaque pas de temps ; la forme stable, en bas à droite, reste identique d’un pas de temps sur l’autre ; le planeur, en haut à droite, se retrouve à l’identique après 4 pas de temps, mais décalé dans l’espace.
Les planeurs sont des structures qui évoluent dans le temps et se retrouvent à l’identique mais déplacés dans la matrice au bout de quelques pas de temps. Le plus simple, en haut à droite dans la Figure IV.3, se déplace en diagonale de trois cases tous les quatre pas de temps. Il existe beaucoup de planeurs différents caractérisés par leur orientation et la direction de leur déplacement, leur périodicité et leur vitesse.
Des conditions initiales aléatoires vont produire des comportements à l’allure chaotique dont surgissent rapidement des formes pouvant appartenir aux classes décrites précédemment. Certaines conditions initiales ont été identifiées et caractérisées pour l’évolution qu’elles suivent et le motif qu’elles dessinent dans le temps ou à un instant donné, par exemple, le clown, qui apparaît à la 111ème itération de l’automate à partir d’une structure initiale en forme de « u » inversé constitué de sept cellules actives (Figure IV.5).
Il existe des recherches pour inventorier les planeurs, oscillateurs ou motifs stables qui existent, ainsi que les conditions initiales au comportement remarquable. Saisir les mots clés game of life » ou « jeu de la vie » sur un moteur de recherche renvoie de nombreux liens vers des bibliothèques répertoriant les configurations initiales particulières connues ou les structures que présente le Jeu de la vie.*
L’objectif à travers l’implémentation de cet automate cellulaire est de vérifier qu’à l’aide de la plateforme, nous sommes capables d’obtenir les formes présentes dans le jeu de la vie (planeurs, formes stables et oscillateurs) et de reproduire des configurations remarquables identifiées dans la littérature telles que des canons à planeurs ou le clown.
