MODULE Visites; IMPORT SIM, STAT, PROCS, LIST, BIN, EVENT; FROM RAND IMPORT Uniform01; FROM RAND1 IMPORT DiscreteDist, CreateDiscreteDist, Discrete, Expon; FROM BIN IMPORT Bin, Take, Give, Avail, WaitList, ServicePolicy; FROM PROCS IMPORT ProcessType, Delay; FROM EVENT IMPORT EventType; FROM MYINOUT IMPORT WriteString, WriteLn; VAR TailleQ : CARDINAL; (* Taille de la file d'attente. *) NbPerdus : CARDINAL; (* Nb. de visiteurs perdus pour la *) (* Repetition courante. *) VisiteOK : Bin; (* Contient un jeton ssi il y a assez *) (* de monde pour demarrer une visite. *) TailleArriv : DiscreteDist; (* Fct. de repartition de la taille *) (* groupes qui arrivent. *) Hotesse : ProcessType; (* Une hotesse. *) GenArrivee : ProcessType; (* Generateur d'arrivees. *) Fermeture : EventType; (* La fermeture du site. *) StatPertes : STAT.Block; (* Stat. sur les pertes pour les *) (* differentes repetitions. *) Rep : CARDINAL; (* No. de la repet. courante. *) i : CARDINAL; V, F : ARRAY [0..3] OF LONGREAL; (* Valeurs possibles de la taille X *) (* d'un groupe, et fonction de *) (* repartition de X. *) PROCEDURE ProcFermeture; BEGIN IF LIST.Size (WaitList (VisiteOK)) = 0 THEN (* Aucune hotesse de libre. *) NbPerdus := NbPerdus + TailleQ END; SIM.Stop END ProcFermeture; PROCEDURE ProcHotesse; VAR Lunch : BOOLEAN; BEGIN Lunch := FALSE; (* N'a pas encore mange. *) WHILE TRUE DO IF (NOT Lunch) AND (SIM.Time () > 12.0) THEN (* Aller manger. *) Delay (0.5); Lunch := TRUE END; Take (1, VisiteOK); IF TailleQ > 15 THEN TailleQ := TailleQ - 15 ELSE TailleQ := 0 END; IF (TailleQ >= 8) THEN (* Il y a encore assez de monde. *) Give (1, VisiteOK) END; Delay (0.75); (* Duree de la visite. *) END END ProcHotesse; PROCEDURE ProcGenArrivee; VAR Temp : CARDINAL ; BEGIN WHILE TRUE DO Delay (Expon (0.05, 1)); IF ((TailleQ > 10) AND (Uniform01 (2) < (FLOAT (TailleQ - 10)) / 30.0) OR (TailleQ >= 40)) THEN (* Ces visiteurs renoncent. *) Temp := TRUNC (Discrete (TailleArriv, 3)) ; NbPerdus := NbPerdus + Temp; ELSE Temp := TRUNC (Discrete (TailleArriv, 3)) ; TailleQ := TailleQ + Temp; IF (TailleQ >= 8) AND (Avail (VisiteOK) = 0) THEN Give (1, VisiteOK) END (* Il y a maintenant assez de monde. *) END END END ProcGenArrivee; PROCEDURE SimulerUneRepetition; BEGIN BIN.Init (VisiteOK); PROCS.KillAll; SIM.Init; TailleQ := 0; NbPerdus := 0; EVENT.Schedule (Fermeture, 16.0, NIL); PROCS.Schedule (GenArrivee, 9.75, NIL); FOR i := 1 TO 3 DO PROCS.Schedule (Hotesse, 10.0, NIL) END; SIM.Start; STAT.Update (StatPertes, FLOAT (NbPerdus)) END SimulerUneRepetition; BEGIN EVENT.Create (Fermeture, ProcFermeture, 'Fermeture du site'); PROCS.Create (GenArrivee, ProcGenArrivee, 2048, "Generateur d'arrivees"); PROCS.Create (Hotesse, ProcHotesse, 2048, 'Une hotesse'); BIN.Create (VisiteOK, Fifo, 'Groupe'); STAT.Create (StatPertes, STAT.Tally, 'Les clients perdus'); FOR i := 0 TO 3 DO V[i] := FLOAT (i + 1) END; F[0] := 0.2; F[1] := 0.8; F[2] := 0.9; F[3] := 1.0; CreateDiscreteDist (TailleArriv, 4, V, F); FOR Rep := 1 TO 10 DO SimulerUneRepetition END; STAT.ReportConfidenceInterval (StatPertes, 0.9) END Visites.