Académique Documents
Professionnel Documents
Culture Documents
SIMULATION DISCRETE
avec
SIMSCRIPT et GPSS
Nicolas FAGART
MARS 1995.
SOMMAIRE.
INTRODUCTION
• I.1) L'exemple:
• I.2) Le Vocabulaire.
• I.3) Le Temps en Simulation Discrète.
• I.4) Arrivées dans le Système
• I.5) Files d'attentes.
• I.6) Listes Chaînées
II SIMSCRIPT
III GPSS
CONCLUSION
BIBLIOGRAPHIE
INTRODUCTION
Cette étude a pour objet, la Simulation discrète. Nous nous attacherons plus particulièrement
à deux langages, qui ont été développés spécialement pour ce type de simulation: GPSS et
SIMSCRIPT.
Nous allons dans un premier temps décrire les principes de base de la Simulation discrète,
afin de familiariser le lecteur avec les problèmes de simulation, et de présenter les fonctions
que devront remplir les langages de simulation.
Ces deux langages sont ceux qui ont été le plus utilisés dans des débuts de la simulation.
FORTRAN était le plus développé au départ, mais son but principal n'était pas la
Simulation, GPSS et SIMSCRIPT ont été eux développé dans ce but. D'autres langages
comme PL/I, COBOL, SIMULA et GASP ont aussi été des bons outils en matière de
simulation, mais moins répandus que GPSS ET SIMSCRIPT.
I.1) L'exemple:
Pour bien comprendre le principe de la simulation discrète, nous nous appuierons au cours
de cette étude sur un exemple très simple: L'utilisation d'une cabine téléphonique par des
usagers. Des usagers arrivent à la cabine téléphonique, désirant téléphoner. Si la cabine est
occupée au moment de leur arrivée, ils doivent rejoindre la file d'attente. Dès que le
téléphone est libéré, la première personne de la file entre dans la cabine, elle y reste pendant
son appel qui dure un certain temps. Ensuite elle quitte la cabine libérant ainsi le téléphone
pour le suivant. La figure 1 représente la scène, et la figure 2 décrit le parcourt d'un usager.
I Introduction à la SIMULATION
Simulation Discrète
DISCRETE.- SIMSCRIPT et GPSS 3
Simulation Discrète - SIMSCRIPT et GPSS
I.2) Le Vocabulaire.
• Les Entités: Ce sont les composants du système qui interagissent. Dans notre
exemple, les usager et le téléphone sont des entités.
• Les Attributs: Ce sont les caractéristiques, les propriétés des entités.
• L'Etat du Système : Il est déterminé par la valeur des attributs des entités, ainsi que
les relations entre ces entités, à un moment donné. L'évolution du système dépend
des changements d'état du système.
• Les Activités :Ce sont tous les processus qui aboutissent à un changement d'état du
système. Ce sont les entités qui entrent en activité. Par exemple, l'arrivée et le départ
d'un usager sont des activités.
• Les Evénements : Ce sont les apparitions des activités à un instant particulier. Un
événement se produit à l'instant ou le téléphone est libéré par un usager. Les
événements doivent être stockés (et étudiés), dans le " Event-Shedule ", qui est le
programme des événements à venir (cela correspond à peu près au " sequencing
set ").
Dans la plupart des simulations, l'écoulement du temps simulé doit être contrôlé. Cela est
automatique dans la plupart des langages dédiés à la simulation. Si ce n'est pas le cas, il faut
un algorithme spécifique pour la gestion du temps.
L'horloge de Simulation (" Simulation clock ") est intimement liée au déroulement des
événements dans le système. Elle permet de classer les événements à venir par ordre dans le
L'unité de temps doit être choisie en fonction des besoins de la simulation. Cela peut varier
de la minute à la nanno-seconde (réaction chimique...), ou encore le siècle (évolution de
rivières...).
Dans l'exemple de la cabine téléphonique, tous les changements d'états sont provoqués par
les arrivées. Dès qu'un usager arrive on peut prévoir son départ en fonction de l'état présent
du système et la distribution des durées d'appel des autres usagers déjà présents dans le
système.
Par exemple, nous pouvons étudier le cas du premier usager, à la première ligne de la figure
3. Son arrivée est programmée pour l'heure 0, et son appel doit durer 3 minutes. La cabine
est libre lors de son arrivée, donc il n'a pas à faire la queue. Comme il n'y a pas de file
d'attente, sa durée totale dans le système sera de 3 minutes.
L'arrivée du deuxième usager est prévue à l'heure de simulation 2, ceci pour effectuer un
appel de 4 minutes. Mais l'usager n°1 ne laissera la cabine qu'à l'heure 3. Celle-ci est donc
occupée lors de l'arrivée du n°2 qui doit alors faire la queue pendant 1 minute. Son temps
total dans le système sera donc de 5 minutes. On peut dès maintenant prévoir son départ
pour l'heure 7.
En général, les heures des arrivées sont calculées grâce à des règles. Par exemple, une
distribution empirique peut être utilisée pour la génération des arrivées. Dans la plupart des
cas, des distributions uniformes ou normales des arrivées rendent bien compte des
phénomènes observés dans la réalité.
Dès que la distribution est connue, il est possible de programmer les arrivées. A ce stade
deux méthodes sont généralement utilisées:
• La plus simple est d'enregistrer (dans une table, par exemple) toutes les dates
d'arrivée, avant le début de la simulation. Ces arrivées peuvent être rangées selon
leur heure de réalisation, chaque événement " arrivée " se produira lorsque l'horloge
de simulation arrivera à la date prévue.
• L'autre méthode, qui est la plus utilisée et la plus économe du point de vue du
stockage de l'information, consiste à programmer les arrivées à au fur et à mesure
que les événements se produisent. Ce n'est qu'à la date de l'arrivée du n°2 que l'on
prévoit celle du n°3. Avec cette méthode, seuls les événements dans un futur immédiat
sont programmés dans le " schedule-event ".
Les files d'attentes sont en fait des Listes. Elles sont caractérisées par la manière dont les
entités y circulent. Les types de liste les plus utilisés sont :
1. FIFO (First in, First out) : Les entités y sortent dans l'ordre dans lequel elles sont
rentrées. Ce sont les files classiques, ce sont elles qui sont le plus utilisées en
simulation. C'est le cas de notre exemple de cabines téléphoniques. C'est aussi le cas
entre autres des voitures faisant la queue à une station service. (Figure 5)
2. LIFO (Last in, First out) : La dernière entité rentrée dans la liste est la première
servie. Ce ont les piles. Ce type de liste est utilisé pour le stockage de matériel en
" pile ". Des voitures embarquées sur un Ferry-boat -n'ayant qu'une rampe de
chargement/déchargement- illustrent ce type de piles: La dernière voiture embarquée
sera la première à débarquer.
3. RANDOM : Chaque entité du " tas " a une même probabilité d'être servie en
premier, indépendamment de leur date d'arrivée ou leur ordre dans la liste. C'est
l'exemple d'un tiragealéatoire des boules au LOTO en imaginant qu'elles sont
rentrées dans l'ordre de leur numéro. (Figure 7)
4. RANKED : Les entités y sont ordonnées suivant la valeur d'un attribut qui leur est
associé. Cet attribut correspond à leur priorité. Il existe divers types de rangement,
par exemple un rangement alphabétique (résultat d'examens, visite médicale...), ou
un rangement suivant l'age, le sexe... Quand deux entités ont la même priorité c'est
généralement la première arrivée qui est la première servie. (Type FIFO par défaut).
Pour modéliser une file d'attente dans un programme de simulation, nous devons créer des
relations entre les différents membres de cette file. Uneliste chaînée est une liste dont chaque
élément est associé à un ou plusieurs pointeurs sur les éléments suivants de cette liste,
comme le montre la figure 9.
Dans une liste chaînée, chaque élément possède au moins un attribut pointeur. Le pointeur
Suiv indique pour chaque élément l'adresse de l'élément suivant. Le pointeurPréc,
(indispensable),indique pour chaque élément, l'adresse de l'élément précédent. Enfin, le
pointeur Début (indispensable) permet d'accéder au premier élément de la liste et le pointeur
Fin, permet d'atteindre le dernier élément de la liste.
Uneliste simplement chaînée (Fig 9) est bien adaptée dans le cas d'une file d'attente de type
FIFO. La dernière entité à rentrer dans la file, ira se placer en queue; Avec le pointeur Fin
on accède au dernier élément, on attribue une nouvelle valeur disponible pour son pointeur
Suiv qui correspond à l'adresse du nouvel élément. Enfin on change la valeur du pointeur
Fin par l'adresse du nouvel élément pour pouvoir y accéder lors de l'arrivée du suivant sans
être obligé de reparcourir toute la file. Le pointeur Suiv du dernier élément lui reste à zéro,
Pour les files LIFO, le même principe est utilisé, mais le nouvel élément est inséré en tête
de liste, pointé par Début, et avec un pointeur Suiv sur l'ancienne tête de file.
Notons que cette procédure de mise à jour des pointeurs peut très bien être utilisée pour
supprimer ou insérer un élément en milieu de la file. Par exemple les événements peuvent
être rangés dans la file suivant leur date de réalisation. Ainsi quand un nouvel élément est
prévu, il doit être inséré dans la file, après avoir trouvé sa position relative. Dans un tel
système l'événement pointé par début est toujours le prochain événement qui se réalisera,
lors de l'incrémentation du temps.
Les listes chaînées multiples simplifient la simulation de problèmes plus complexes, mais
elles prennent un peu plus de place en mémoire, à cause des nouveaux pointeurs (fig 10).
Avec ce type de liste beaucoup de pointeurs peuvent être associés à un seul élément. Les
listes doublement chaînées (figure 9) sont particulièrement pratiques, elles permettent de
modéliser des files FIFO ou LIFO, et sont très utilisées pour les listes RANKED ou
RANDOM. En effet un élément peut être atteint en partant de n'importe quel autre élément
de la file.
Les pointeurs peuvent aussi être utilisés pour relier certains éléments qui possèdent un
même attribut. Par exemple les éléments d'une liste chaînée peuvent avoir un attribut
" couleur ". Un pointeur coul permettrai ainsi de relier tous les éléments d'une même
couleur. On pourrait ainsi parcourir tous les éléments d'une même couleur sans passer par
tous les éléments de la liste globale. Il suffit de connaître le premier élément de cette couleur
qui peut être désigné par le pointeur " Premier vert " par exemple.
Un élément peut très bien appartenir à plusieurs liste à la fois. Il suffit qu'il possède autant
de pointeurs qu'il y a de liste (ex. figure 10). On remarque que pour un élément qui
n'appartient pas à une liste, les pointeurs prec et suiv correspondant à la liste 1,2, ou 3,
seront à zéro. Ceci est à ne pas confondre avec les extrémités de la file qui possèdent aussi
un pointeur à zéro.
Les procédés de listes chaînées posent certains problèmes de stockage. Les listes étant
" extensibles ", la procédure d'élimination d'un élément doit être étudiée minutieusement.
Par exemple lors de la suppression de l'élément n°2 dans la liste chaînée de la figure 9, une
fois que les pointeurs des deux éléments précédent et suivant sont mis à jour, il n'y a plus
aucun moyen d'atteindre l'élément n°2: la liste court-circuite cet élément. Pourtant la place
de cet élément qui était réservé en mémoire, n'a pas été libérée. Il faut bien faire attention à
libérer cette espace. Heureusement des langages comme GPSS, PL/I, et SIMSCRIPT
s'occupe de cette libération automatiquement, ce qui n'est pas le cas de beaucoup d'autre
langages (en particulier les langages assemblés).
II SIMSCRIPT
Les concepts de bases de SIMSCRIPT sont sensiblement les mêmes que ceux évoqués dans
le chapitre précédent. Il existe des entités auxquelles il est possible d'associer desattributs. Il
est possible de simuler différentes interactions entre les entités, telles que des files d'attente.
Les activités sont définies par des subroutines (FORTRAN), que l'on appellera des routines
d'événements.
Tous ces concepts existaient déjà avec le FORTRAN, ou le PL/I, mais SIMSCRIPT offre, en
plus des possibilités du FORTRAN, de nombreux avantages dédiés à la simulation discrète.
Par exemple le mécanisme d'horloge pour le programme des événements est automatique.
De même l'utilisation des différents types de files d'attente est beaucoup simplifiée, la
gestion des pointeurs étant transparente pour l'utilisateur.
1. Section de définitions
2. Déclaration des routines événements
3. Routines d'événements
4. Partie d'initialisation
5. Listeévénements exogènes
1- Dans la partie de définitions les entités, attributs, et les autres variables du système sont
définies, cela correspond aux déclarations des variables dans un langage comme le
PASCAL. La figure 11 montre un exemple de code de la section de définition. SIMSCRIPT
différencie deux types d'entités: les entités permanentes, et les entitéstemporaires.
Les entités temporaires représentent des éléments qui seront créés et détruits de nombreuses
fois pendant la simulation. Le code T dans la deuxième colonne du programme (fig. 11)
signifie que MAN est une entité temporaire.Cette entité peut représenter un usager qui entre
dans le système pour téléphoner, après être sorti de la cabine téléphonique, il est éliminé du
système. Plusieurs attributs sont associés à cette entité: TIBTH, TTOQ, SQUE, STEL. Ces
attributs sont porteurs d'information, par exemple TIBTH correspond au temps total
d'utilisation de la cabine.
Les entités permanentes sont utilisées pour définir des entités, variables, pointeurs, tableaux
qui sont les caractéristiques permanentes du modèle global, et peuvent être référencées tout
au long de la simulation. Comme leur nom l'indique, ces entités ne peuvent être détruites.
De telles variables peuvent servir à transférer de l'information d'une partie à l'autre du
modèle, supporter de l'information concernant tout le modèle, ou définir les attributs du
système global. Par exemple la variable permanente FNUSE, peut correspondre au nombre
d'entités MAN qui sont entré dans la cabine téléphonique.
Les files d'attentes sont aussi définies dans cette section. Par exemple QUE et TEL sont
deux files FIFO (codées par F dans la colonne 57 sur la figure 11). Les entités temporaires
qui doivent rentrer dans des files d'attentes doivent avoir comme attributs des pointeurs qui
permettront de les chaîner entre elles dans ces files. MAN possède deux attributs SQUE et
STEL qui pointent sur les entités suivantes dans chacune des queues. Ces files doivent aussi
avoir des pointeurs début (FQUE et FTEL) et fin (LQUE, LTEL) qui sont des variables
permanentes.
2- La liste des routines d'événements correspond aux déclarations de ces routines. Il existe
deux types de routines d'événements en SIMSCRIPT, les routines exogènes et les routines
endogènes.
Comme leur nom l'indique les routines endogènes ne peuvent être utilisées qu'à l'intérieur
du système de simulation contrairement aux routines exogènes.
4- Section d'initialisation.
La deuxième option consiste à les affecter individuellement par une valeur (en colonne
65-67), et en plaçant un " R " dans la colonne 12. (LOWT, HIT, LOWC, HIC). Dès le début
de la simulation ces variables seront ainsi affectées.
5- Liste des événements exogènes. C'est la dernière partie du programme. Elle consiste à
enregistrer chaque événement en correspondance avec la routine d'événements exogènes
associée (grâce à un numéro d'identification), ainsi que l'heure à laquelle la routine doit être
exécutée. En SIMSCRIPT I.5, une seule routine d'événement exogène est nécessaire, pour
lancer la simulation.
Notons qu'une routine peut tout à fait prévoir de nouveaux événements endogènes pour la
suite, et les insérer ainsi dans l'event-schedule. Cette liste des événements est constamment
remise à jour. Après l'exécution d'une routine, le premier événement est éliminé, et de
nouveaux apparaissent au fur et à mesure. La mise à jour de la file est automatique.
SIMSCRIPT est très similaire au FORTRAN. La plus grande ressemblance est la syntaxe
utilisée pour la liste des instructions exécutables des routines d'événements. Nous allons ici
commenter ces instructions, en soulignant leurs spécificités et leur utilisation en simulation.
La table (figure 14) fait l'inventaire des instructions les plus utilisées en simulation.
Les instructions de SIMSCRIPT sont codées sur des cases, exactement comme FORTRAN.
Le corps des instructions est codé entre les colonnes 7 et 72. Les colonnes 2 à 5 sont
réservées pour les labels, et les colonnes 73 à 80 sont ignorées par le compilateur. Comme
en FORTRAN la lettre C apparaît dans une case pour indiquer que ce qui suit est un
commentaire.
CREATE MAN
réservera de la place en mémoire pour une entité de type MAN (définie dans la figure 11).
Sans ce système d'allocation dynamique, une simulation SIMSCRIPT occuperait
énormément de mémoire. L'instruction DESTROY est nécessaire pour libérer l'espace
réservé pour l'entité temporaire. Par exemple l'instruction.
DESTROY MAN
Quand il est nécessaire de créer deux entités MAN en même temps dans le système, il faut
utiliser une variable locale, pour pouvoir les différencier. Une variable locale n'est connue
du système qu'à l'intérieur de la routine d'événement à l'intérieur de laquelle elle a été
créee. Par exemple les instructions,
définissent deux variables locales JERRY et LARRY. De ce fait il est possible de distinguer
les attributs de ces deux entités MAN coexistant dans le système. TIBTH(JERRY)
représentera la longueur de l'appel téléphonique de JERRY. Dans ce cas, l'instruction
DESTROY devra préciser quelle entité MAN doit être détruite. L'instruction
Les routines d'événements contiennent souvent une séquence d'instructions qui crée et place
dans l'event-schedule un événement endogène. Comme un événement endogène est un type
d'entité temporaire, la création d'un événement est réalisée avec une instruction CREATE.
Par exemple, L'instruction
CREATE ARVE
crée un événement nommé ARVE. Le nom utilisé pour l'événement doit aussi être le nom
d'une routine d'événement endogène, défini dans la section des routines d'événements.
Quand cet événement arrivera en premier dans la liste des événements, c'est la routine
associée qui sera exécutée. L'instruction CAUSE permet de placer des événements dans
l'event-schedule:
La fonction TIME étant automatiquement définie dans le système, l'événement sera inséré
dans la liste avec un attribut de temps de 12,5 unités de temps dans le futur. L'exécution de
la routine d'événement se réalisera donc à cette date.
Des événements " arrivée ", placés dans la queue, peuvent en sortir avant leur exécution
avec une instruction CANCEL. Par exemple si la queue devant la cabine téléphonique est
estimée trop longue on peut en faire sortir des individus grâce à l'instruction :
CANCEL ARVE
Cette instruction n'a pas pour autant détruit l'événement. Celui-ci est toujours en mémoire,
et il ne faudra pas oublier de libérer la place qu'il occupe, avec un DESTROY.
créera une entité temporaire LARRY et la placera dans la file QUE. Si QUE a été définie
comme une file RANKED, l'entité spécifique pourra être classée au moyen de
l'instruction:
Ce moyen spécifique de classement de files est autorisé car SIMSCRIPT utilise des listes
doublement chaînées (Figure 9). Pour les files FIFO et LIFO, qui sont simplement chaînées,
les seules instructions utilisées sont :
CREATE MAN
------
------
------
------
Si la file QUE est une FIFO, MAN sera placé en queue de QUE par l'instruction FILE,
tandis que si c'est une LIFO, FILE aura pour effet de placer MAN en tête de QUE.
L'instruction REMOVEFIRST prend toujours l'entité qui est en tête de la file.
L'instruction IF est particulièrement intéressante pour prendre des décisions au sujet des
files d'attentes. En effet il est possible de tester si une file est vide ou ne l'est pas:
6 IF QUE IS EMPTY, GO TO 7
GO TO 1000
7 ------
Avec ces instructions le REMOVE sera court-circuité dans le cas d'une file d'attente vide.
LET IX(3)=Y+1.5*Z
L'expression à droite du signe égal est évaluée, et cette valeur est placée en IX(3), avec la
conversion de Flottant en Entier si nécessaire.
Les instructions ACCUMULATE et COMPUTE sont très utiles pour effectuer des
statistiques. ACCUMULATE est généralement utilisé pour accumuler des totaux dans le
temps. Par exemple, le temps cumulé d'une file QUE peut être évaluée lors de l'exécution
des instructions
Ici TLAST et l'heure du dernier changement de taille de la file, et FNQUE est le nombre
d'éléments de la file. L'instruction doit être placée à chaque fois que l'on modifie la file.
Cette instruction se résume à
CUMQ=CUMQ+FNQUE*(TIME-TLAST)
TLAST=TIME
L'instruction COMPUTE provoque exécution du calcul des statistiques. Par exemple pour
calculer la moyenne XMEAN et l'écart type XSTD des K premiers éléments du tableau X,
on peut utiliser les instructions suivantes:
L'exemple précédent montre aussi l'utilisation d'une phrase de contrôle. L'existence de ces
LET X(I) = Z(I) * Y(I) FOR I = (1) (K*J) WITH (Z(I)) LT (6.3)
M=K*J
DO 1 I=1,M
1 IF (Z(I).LT.6.3), X(I)=Z(I)*Y(I)
LET TOTME = TOTME + TIME - TTOQ ( JOE ), FOR EACH JOE IN QUE
Les boucles en SIMSCRIPT sont assez simples d'utilisations, comme le montre l'exemple
suivant:
13 LOOP
Dans cet exemple, 20 entités MAN ont été crées et sont entré dans la file d'attente QUE.
Dans cette partie, nous allons réaliser un programme complet SIMSCRIPT, pour la
simulation de l'utilisation de la cabine téléphonique, dont nous avions déjà exposé le
problème au début de cette étude.
Le problème étant assez simple, il est possible de le représenter sous la forme d'un
organigramme (figure 15). Ce programme contient trois routines d'événement, la routine
exogène CRNKUP, et les deux routines endogènes ARVE et LEAV.
En SIMSCRIPT I.V, un événement exogène est nécessaire pour faire démarrer l'algorithme
de simulation, car aucun événement endogène ne peut être placé dans la liste des
événements avant qu'une routine ne soit exécutée. Dans notre exemple c'est la routine
d'événement exogène CRNKUP qui sert de " starter " pour le modèle. Dès que la routine
CRNKUP est lancée, l'entité temporaire MAN est crée, et des attributs lui sont affectés.
TTOQ, qui sera plus tard utilisé pour le calcul du temps total en minutes de la durée
d'attente du MAN dans la file d'attente, est pour l'instant initialisé à zéro grâce à l'instruction
LET TTOQ(MAN)=TIME
L'attribut TIBTH est utilisé pour stoker la durée de l'appel du MAN. Ce temps est calculé
grâce à un générateur de nombres aléatoires (RANDI) dans un intervalle uniforme
[LOWT,HIT]. La valeur du nombre aléatoire est divisée par 1 440 (nombre de minutes dans
un jour), car l'unité de temps en SIMSCRIPT est le jour. La première entité MAN accédera
directement à la cabine, car il est le seul dans le système. Cependant, son départ peut être
prévu, pour TIBTH(MAN) jours dans le futur, grâce aux instructions
CREATE LEAV
MAN sera alors placé dans la liste TEL, qui représente la cabine téléphonique. Cette liste ne
contient qu'une seule entité à la fois, et la variable permanente du système
FNUSE comptabilisera le nombre d'entités qui seront passé par la cabine. Dès lors que
MAN est placé dans TEL, l'événement endogène ARVE est prévu, afin de créer la prochaine
arrivée. L'événement est évidemment en tête de liste puisqu'il est le seul, pour l'instant.
C'est donc lui qui sera exécuté lorsque le programme de contrôle reprendra la main, après que
l'instruction RETURN, a été rencontrée.
La routine d'événement CRNKUP ne sera plus jamais exécutée, durant toute la simulation,
car aucun autre événement exogène n'est prévu dans le modèle.
A chaque fois qu'une instruction RETURN est rencontrée, l'algorithme général recherche le
prochain événement, et il lance la routine qui lui est associée. Cet événement c'est celui qui
est en tête de la liste des événements, dans l'event-schedule. Si c'est un ARVE, l'horloge
est mise à l'heure de cet événement, et la routine ARVE est exécutée. Cette routine a quatre
buts:
Si l'algorithme global trouve un LEAV comme prochain événement, il met à jour l'horloge,
puis exécute la routine LEAV. Celle-ci a cinq buts:
III GPSS
Le seul but de GPSS est de faire de la simulation. Il a été conçu avec le principe que tous les
systèmes peuvent être simulés correctement, avec uniquement quelques types d'entités:
Des entités dynamiques, des entités d'équipement, des entités statistiques, et des entités
opérationnelles.
Les entités dynamiques de GPSS sont appelées des transactions. Les transactions sont
créées et détruites en cours de simulation, à l'image des entités temporaires de SIMSCRIPT.
Par exemple, les utilisateurs de la cabine téléphonique, dans notre exemple déjà étudié, se
résumeraient à des transactions en GPSS. Les activités résultent de l'interaction des
transactions avec les autres entités; Lors du passage de transactions dans le système, Les
attributs de transactions sont définis grâce à des listes de paramètres associées à chaque
transaction.
Les entités d'équipement sont utilisées pour modéliser les équipements utilisés pour les
transactions (Téléphones, photocopieuses,...). Les facilities, par exemple, correspondent à un
équipement qui ne sert qu'à un utilisateur à la fois. S'il n'y a qu'un téléphone, on peut le
modéliser grâce au concept de facilities. Mais GPSS autorise l'utilisation multiple d'un
même équipement. Celui-ci est alors appelé storage. Dans notre cas par exemple il pourrait
y avoir une cabine avec trois téléphones, GPSS est capable de les gérer comme une seule
entité storage.
De plus, GPSS dresse automatiquement des statistiques sur l'utilisation des équipements, les
contenances moyennes des files d'attentes, les entrées et les sorties... Les résultats finaux
sont délivrés automatiquement en fin de simulation, ce qui simplifie beaucoup le travail de
synthèse des résultats et allège l'implémentation. Les informations statistiques sont traitées
comme des attributs des différentes entités, et on peut y avoir accès à n'importe quel
moment du programme. Il est ainsi possible d'afficher au fur et à mesure les informations
statistiques, sans interrompre la simulation.
GPSS propose de nombreuses entités statistiques pour analyser la simulation, Les " Queues
entities " et les " chain entitie " sont utilisées pour simuler et mesurer les rapports
d'utilisation entres les différentes entités d'équipement. Les " chain entities " ou entités
chaînées sont aussi utilisées pour modéliser des files d'attentes complexes. Les différentes
fréquences de distributions sont collectées dans des tables, au cours du processus de
simulation.
Les entités opérationnelles de GPSS sont appelées des blocks. Ils correspondent à des
instructions. En GPSS, les blocks déterminent la logique du système, en contrôlant les
interactions des transactions. Par exemple, certains blocks contrôlent l'utilisation des
équipements par les transactions. D'autres blocks affectent les paramètres (ou attributs) des
transactions. Certains contrôlent les sorties... Il existe une quarantaine de blocks différents en
GPSS. L'essence de GPSS réside en les actions résultant de l'interaction des blocks et des
transactions.
GPSS contrôle automatiquement le flux des transactions, d'un block à l'autre. Le programme
de contrôle sait en permanence quelle est la prochaine transaction qui doit se produire, dans
un block, et le temps qu'elle prendra, grâce au système d'horloge qui range les événements
par ordre chronologique. Les transactions sont généralement stockées dans des files du type
" premier entré - premier servi " = FIFO.
Quand une opération prévue ne peut être effectuée, par exemple quand il n'y a pas
d'équipement disponible, le programme de contrôle place la transaction en attente, dans un
état d'inactivité temporaire. Une recherche est alors effectuée pour trouver la transaction
suivante. L'horloge est alors mise à jour puis la transaction est effectuée. Généralement le la
simulation s'arrête après un nombre déterminé de transactions.
Les attributs et les entités sont très utilisés en GPSS. Il est possible de définir des entités
" fonctions " pour définir des distributions empiriques complexes, ou des distributions
uniformes. GPSS met de plus à notre disposition huit générateurs de nombres aléatoires.
A l'image de SIMSCRIPT, GPSS est codé avec un système de grille. Une instruction (ou
block) de GPSS s'étale sur 80 colonnes. Les colonnes de 8 à 18 contiennent les mots clefs. A
partir de la colonne 19, ce sont les opérandes de spécification des blocks. Les commentaires
peuvent être insérés à la fin de chaque blocks, après la dernière opérande.
TERMINATE 1
détruira la transaction qui sera présente dans ce block. A chaque instruction de ce type, une
transaction est éliminée du block. Quand il n'y a plus aucune transaction, la simulation est
terminée.
GENERATE 22,12
créera des transactions tout les x unités de temps, avec x = 22 +/- 12, c'est à dire un nombre
aléatoire compris entre 10 et 34. Des distributions plus complexes sont possibles, grâce aux
fonctions.
ADVANCE 15,5
indique que l'équipement sera utilisé pendant 15 plus ou moins 5 minutes. Les deux autres
blocks, correspondent au type d'utilisation de l'équipement. Les instructions SEIZE et
RELEASE sont utilisés dans le cas de facilities. Pour simuler l'utilisation d'une cabine
téléphonique simple pendant 10 à 20 minutes, on utilisera la syntaxe suivante:
SEIZE PHONE
ADVANCE 15,5
RELEASE PHONE
Lorsqu'une transaction entre dans le block SEIZE, la facilityPHONE passe de l'état vacant
à l'état occupé. Elle sera de nouveau vacante lors de l'exécution de l'instruction
RELEASEPHONE. Mais entre temps, la transaction est bloquée au niveau du block
ADVANCE, durant une période variant aléatoirement entre 10 et 20 minutes dans notre
exemple. ADVANCE correspond à l'utilisation de la facility.
Dans le cas d'un équipement multiple, qui a la capacité d'accueillir plusieurs utilisateurs en
même temps, on n'utilise plus les instructions SEIZE et RELEASE (dédiées aux
facilities), mais ENTER et LEAVE qui s'appliquent à des storages. Par exemple une cabine
avec trois téléphones sera modélisée par un storageTEL, dont l'attribut capacity aura la
valeur 3, La capacity étant le nombre maximum de transactions en même temps autorisées
dans le storage. Pour les storages comme pour les facilities des statistiques sont effectuées
automatiquement au cours de la simulation, lors de chaque passage d'une dans un des
block définis ci dessus.
Il est très courant au cours d'une simulation, que les facilities soient occupées, ou que le
storage soit plein. On a donc recours aux files d'attentes. Les instructions QUEUE et
DEPART sont destinées à faire rentrer et sortir des transactions dans une file d'attente de
type FIFO. Ces deux blocks sont généralement associés à des SEIZE ou ENTER. On peut
ainsi avoir la liste d'instruction,
QUEUE LINE
SEIZE PHONE
DEPART LINE
Dans cet exemple, l'utilisateur est inséré dans la file d'attente dans tous les cas. Puis si
PHONE est disponible, il est éjecté de la file, après avoir réservé le téléphone.
PHONE repasse donc dans un état occupé. Si PHONE était occupé au départ, l'utilisateur
patiente dans la file d'attente jusqu'à son tour. Les statistiques sur la taille, les entrées et les
sorties des files d'attentes sont aussi automatiques. (moyenne, maxi, mini, temps cumulé...).
Les Tests en GPSS sont très utilisés, ils permettent entre autres, de contrôler les mouvements
de transactions, les tailles des files. Ils peuvent s'appliquer sur les attributs des files, ou
activity. Par exemple Q$LINE est un attribut de la queue LINE, correspondant à la taille de
cette file d'attente.
QUEUE LINE
Ces deux instructions autoriseront la rentrée dans la file d'attente, uniquement si celle-ci
contient moins de dix activités. ( L correspond à LESSTHAN ). Dans le cas contraire,
l'activité est envoyée au block portant le labelAWAY.
L'instruction TRANSFER est aussi utilisée pour contrôler le transfert d'éléments dans le
système:
TRANSFER 6,BLCK1,BLCK2
Cette instruction joue le rôle d'un répartiteur: dans 40 % des cas, l'activité sera transférée
dans le blockBLCK1, et dans 60 % elle sera transférée dans le blockBLOCK2.
Le but de la simulation est de valider les données statistiques qu'elle génère. La plupart de
ces données sont stockées dans des tables automatiquement, mais il est possible de fabriquer
ces tables à la demande, avec l'instruction TABULATE.
TABULATE XTME
GPSS utilise des definition cards définir la plupart des entités utilisées dans la simulation.
Par exemple la table XTME, pour le temps de transit, peut être définie dans les definition
cards de la manière suivante:
Cette définition impliquera le stockage des temps de transits (codés M1), dans une table
statistique, comprenant 50 intervalles, commençant à zéro, et allant jusqu'à 20. La
capacity de storage est aussi définie dans les definition cards, ainsi que les variables
numériques et les entités calculées comme les fonctions aléatoires.
En plus des definition cards, GPSS utilise des control cards, pour le contrôle externe, sur
toute la durée de la simulation. Par exemple, l'instruction START est utilisée en conjonction
avec le blockTERMINATE, pour délimiter la longueur d'une simulation. Le compteur de
transactions est affecté au départ avec l'instruction START. Puis chaque TERMINATE a
pour effet de décrémenter ce compteur. L'instruction:
START 2500
marquera le début de la simulation. La simulation s'arrêtera après que les 2500 transactions
sont passées dans le block TERMINATE (avec un 1 en colonne 19).
Les instructions de contrôle CLEAR et RESET sont utilisées pour relancer le système
plusieurs fois. Plusieurs simulations peuvent être ainsi effectuées séquenciellement, avec
quelques modifications à chaque fois. Cette possibilité de GPSS favorise l'étude des cas
sensibles. Par exemple avec la séquence suivante,
GENERATE 15,5
------
------
------
------
TERMINATE 1
START 1 000
CLEAR
START 1000
Le modèle sera executé deux fois de suite. Pour les 1 000 premières transactions, le block
ADVANCE, correspondant à la durée d'utilisation d'un service, aura une valeur entre 5 et
15. Et pour les 1 000 suivantes, la durée du service sera comprise entre 10 et 20. Ces petites
variations dans un système peuvent conduire à des énormes variations, au vu des
statistiques, avec des engorgements des files d'attente, et des réactions en chaîne. C'est
pourquoi, cette faculté de GPSS est non négligeable.
L'instruction de contrôle SIMULATE est indispensable. C'est elle qui lance véritablement la
simulation. Sans elle, le compilateur analysera tout le programme, mais aucune simulation
ne sera exécutée. De même l'instruction END est nécessaire pour le compilateur. Ce doit
être la dernière instruction du programme.
Les utilisateurs sont représentés par des transactions. Ils arrivent dans le système avec un
blockGENERATE, Avec un intervalle de temps entre chaque arrivée suivant une
distribution de densité exponentielle négative, de moyenne 15 minutes. Cette distribution est
spécifiée grâce à la fonction NEXP, définie au début du programme (figure 17 et 18).
Une transaction entrant dans le système est immédiatement placée dans la file d'attente
LINE, ou elle restera, jusqu'à ce que la facilityPHONE soit disponible. Elle sera alors
autorisée à s'en servir et quitter la file LINE. Une fois que la transaction arrive dans le
blockADVANCE, elle y reste durant une période aléatoire tirée entre 5 et 15 minutes.Ensuite
la transaction entre dans le blockRELEASE, elle libère alors la facility pour la
transaction suivante dans la file d'attente. Notre transaction passe alors dans le
blockTABULATE, ou elle marque le temps qu'elle a passé dans le système, en vue des
statistiques.
Les instructions de contrôle en fin de programme spécifient que le modèle doit être relancé
une seconde fois, après avoir nettoyé le système (avec un CLEAR). La figure 19 montre les
résultats statistiques, des deux simulations.
CONCLUSION
SIMULA est un langage de simulation qui a été bien plus utilisé en Europe qu'aux
Etats-Unis. De même que SIMSCRIPT était une extension du FORTRAN, SIMULA est
une extension du langage ALGOL. En SIMULA, le système de simulation est vu comme
une liste de processus. La simulation est réalisée par des blocs de programme, correspondant
aux processus.
GASP II est un autre langage, avec la même philosophie que SIMSCRIPT. Il consiste en
une série de subroutines FORTRAN effectuant des tâches spécifiques à la simulation.
Cependant ce langage a été proportionnellement assez développé sur les petites machines.
Mais il ne permet pas de modéliser des systèmes très complexes de simulation.
Les deux langages de simulation discrète, qui ont connu le plus grand développement,
particulièrement aux Etats Unis, sont incontestablement GPSS, et SIMSCRIPT.
GPSS est un langage relativement facile à apprendre pour un débutant, dès que la logique
des blocks est comprise. Ceux qui n'ont pas l'habitude de programmer trouveront GPSS
plus facile que SIMSCRIPT parce que:
Mais pour des problèmes très compliqués, difficile à modéliser, il est plus difficile de
travailler avec GPSS. SIMSCRIPT est plus souple d'utilisation, et s'adapte plus facilement à
des structures compliquées. Cependant un programmeur expérimenté en GPSS arrivera
Un problème de la plupart des versions de GPSS ets que les variables sont gardées avec
toutes les valeurs: les flottants n'existent pas vraiment. Cela pause des problèmes d'échelle
et de précision dans les opérations arithmétiques, surtout la division. Par exemple même si
beaucoup de problèmes peuvent être modélisés avec une unité de temps d'une heure, il est
souvent pratique de disposer des secondes. Cela oblige souvent à faire des reconversions
avec des facteurs d'échelle. Alors que SIMSCRIPT dispose des notations à virgule flottante,
qui nous affranchissent de cette difficulté.
GPSS est de toute façon le langage de simulation qui a été le plus développé, et implémenté
sur le plus grand nombre de machines. Une des raisons de son développement est qu'il était
très facilement disponible gratuitement sur les machines IBM. SIMSCRIPT n'a pas eu ce
support pour se développer.
Pour résumer SIMSCRIPT est plus rapide, et un peu plus puissant, mais plus compliqué,
tandis que GPSS est plus facile à apprendre, plus léger, et a été plus développé.
BIBLIOGRAPHIE
deO.J.DAHL, 1968
Ed. F. GENUYS