MODULE Banque2; IMPORT SIM, EVENT, STAT, LIST; FROM EVENT IMPORT EventType, EventNotice, CancelNotice, NoticeTime, Schedule, ScheduleNotice; FROM RAND IMPORT Uniform01; FROM RAND1 IMPORT Expon; FROM NUM IMPORT LIToLR; CONST Minute = 1.0 / 60.0; (* Une minute. *) VAR D, U : LONGREAL; (* Tampons. *) NCais : LONGINT; (* Nb. de caissiers. *) NOcc : LONGINT; (* Nb. de caissiers occupes. *) NAtt : LONGINT; (* Nb. de clients en attente. *) NServis : LONGINT; (* Nb. servis aujourd'hui. *) Rep : LONGINT; (* Repetition courante. *) DelaiMoyen : LONGREAL; (* Moy. inter-arrivees. *) Prochain : EventNotice; (* Prochaine arrivee. *) E9h45, E10h, E11h, E14h, E15h, Arrivee, Depart : EventType; StatServis, Attente, AttenteMoy : STAT.Block; PROCEDURE Proc9h45; BEGIN NCais := 0; NOcc := 0; NAtt := 0; NServis := 0; DelaiMoyen := 2.0 * Minute; ScheduleNotice (Arrivee, Expon (DelaiMoyen, 1), NIL, Prochain); END Proc9h45; PROCEDURE Proc10h; BEGIN U := Uniform01 (3); NCais := 3; IF U < 0.2 THEN NCais := 2; IF U < 0.05 THEN NCais := 1 END END; WHILE ((NAtt > 0) AND (NOcc < NCais)) DO INC (NOcc); DEC (NAtt); Schedule (Depart, Expon (Minute, 2) + Expon (Minute, 2), NIL) END END Proc10h; PROCEDURE Proc11h; BEGIN D := NoticeTime (Prochain) - SIM.Time (); CancelNotice (Prochain); ScheduleNotice (Arrivee, D / 2.0, NIL, Prochain); DelaiMoyen := Minute END Proc11h; PROCEDURE Proc14h; BEGIN D := NoticeTime (Prochain) - SIM.Time (); CancelNotice (Prochain); ScheduleNotice (Arrivee, 2.0 * D, NIL, Prochain); DelaiMoyen := 2.0 * Minute END Proc14h; PROCEDURE Proc15h; BEGIN CancelNotice (Prochain) END Proc15h; PROCEDURE Balk () : BOOLEAN; BEGIN RETURN ((NAtt > 9) OR ((NAtt > 5) AND (5.0 * Uniform01 (4) < LIToLR (NAtt - 5)))) END Balk; PROCEDURE ProcArrivee; BEGIN ScheduleNotice (Arrivee, Expon (DelaiMoyen, 1), NIL, Prochain); IF NOcc < NCais THEN INC (NOcc); Schedule (Depart, Expon (Minute, 2) + Expon (Minute, 2), NIL); ELSE IF NOT Balk () THEN INC (NAtt); STAT.Update (Attente, LIToLR (NAtt)) END END END ProcArrivee; PROCEDURE ProcDepart; BEGIN INC (NServis); IF NAtt > 0 THEN DEC (NAtt); Schedule (Depart, Expon (Minute, 2) + Expon (Minute, 2), NIL); STAT.Update (Attente, LIToLR (NAtt)) ELSE DEC (NOcc) END END ProcDepart; PROCEDURE UnJour; BEGIN SIM.Init; STAT.Init (Attente); Schedule (E9h45, 9.75, NIL); Schedule (E10h, 10.0, NIL); Schedule (E11h, 11.0, NIL); Schedule (E14h, 14.0, NIL); Schedule (E15h, 15.0, NIL); SIM.Start; STAT.Update (StatServis, LIToLR (NServis)); STAT.Update (AttenteMoy, STAT.Sum (Attente)) END UnJour; BEGIN EVENT.Create (E9h45, Proc9h45, 'Demarrage'); EVENT.Create (E10h, Proc10h, 'Ouverture'); EVENT.Create (E11h, Proc11h, '11 heures'); EVENT.Create (E14h, Proc14h, '14 heures'); EVENT.Create (E15h, Proc15h, 'Fermeture'); EVENT.Create (Arrivee, ProcArrivee, "Arrivee d'un client"); EVENT.Create (Depart, ProcDepart, "Depart d'un client"); STAT.Create (StatServis, STAT.Tally, 'Nb. servis par jour'); STAT.Create (Attente, STAT.Accumulate, "Attente cumulee aujourd'hui (heures)"); STAT.Create (AttenteMoy, STAT.Tally, "Attente moy. par jour (heures)"); FOR Rep := 1 TO 100 DO UnJour END; STAT.Report (StatServis); STAT.Report (AttenteMoy) END Banque2.