'' Seilbahnsimulation (prozeßorientiert) '' preamble normally, mode is undefined processes include Seilbahn, Kunde, Kundengenerator, FinalReport every Seilbahn may belong to an wartende_Seilbahn every Kunde has an id and may belong to a sitzende_Kunden and a fahrende_Kunden define id as an integer variable '' Warteschlangen zur Prozeßsynchronisation the system owns the wartende_Seilbahn, the fahrende_Kunden and the sitzende_Kunden define sitzende_Kunden, fahrende_Kunden and wartende_Seilbahn as FIFO sets resources include Sitzplatz '' private Zeiteinheiten define Sekunden to mean minutes define Minuten to mean hours define Stunden to mean units '' globale Variable define SimZeit, LambdaKunde, Wartezeit, Abstand, LetzteFahrt as double Variables define MinAuslastung, Counter, ExtraCounter, Auslastung as integer variables '' Statistikvariable tally SumKunden as the sum, mittlereAuslastung as the mean and SumFahrten as the Number of Auslastung tally mittlererAbstand as the mean of Abstand tally mittlereWartezeit as the mean, Warte.Histo( 0 to 36 by 2) as the histogram of Wartezeit accumulate Warteschlange( 0 to 90 by 5 ) as the Histogram of n.q.sitzplatz end ''preamble main skip 2 lines print 3 lines thus Seilbahnsimulation ( prozeßorientiert) ====================================== call readData skip 2 lines print 1 line thus --------------> Simulationslauf beginnt ! call init start simulation end ''main routine to readData '' Einlesen der Daten print 1 line thus ___ Dateneingabe ___ skip 1 line print 1 line thus Simulationsdauer ( in Stunden angeben!) : read SimZeit print 1 line thus Abfahrtslevel (Anzahl Fahrgaeste; <=30 ) : read MinAuslastung print 1 line thus Ankunftsintensität der Fahrgaeste ( in 1/min) : read LambdaKunde end ''readData routine Init ''Initialisierung der Ressourcen, Starten der Prozesse create every Sitzplatz(1) let u.sitzplatz(1) = 30 let hours.v = 60 activate a FinalReport in SimZeit Stunden activate a Seilbahn now activate a KundenGenerator now end ''Init process KundenGenerator '' dient der Erzeugung von Kunden '' mit exponentialverteilten Zwischenankunftszeiten Until time.v > SimZeit do add 1 to Counter activate a Kunde given Counter now wait exponential.f(1/LambdaKunde,1) Minuten loop end process Seilbahn '' modelliert die Seilbahnfahrten define frei as an integer variable ''verwaltet die Zahl der freien Plaetze '' in einer fahrenden Bahn define Warteschlangenlaenge as an integer variable define befoerderter_Kunde as a pointer variable let frei = u.sitzplatz(1) request frei units of sitzplatz(1) ''alle Sitzplaetze zu Beginn sperren let LetzteFahrt = time.v wait 10 Minuten ''auf ersten potentiellen Abfahrtzeitpunkt warten Until time.v > SimZeit do '' Bahn ist angekommen; '' Die benutzten bzw. gesperrten Sitzplaetze sind noch okkupiert '' Alle während der letzten Fahrt eingetroffenen neuen Kunden stehen '' noch in der Warteschlange. '' Zuerst werden alle beförderten Kunden reaktiviert, damit diese ihre '' Plätze freigeben können. Das geschieht aber erst in den Kundenpro- '' zessen, die sequentiell unmittelbar nach der nächsten Verzögerung '' dieses Seilbahnprozesses (durch eine WAIT- bzw. SUSPEND - Anweisung) '' abgearbeitet werden. while fahrende_Kunden is not empty do remove the first befoerderter_Kunde from fahrende_Kunden reactivate the Kunde called befoerderter_Kunde now loop '' Freigabe der in der letzten Fahrt gesperrten Plaetze '' (Achtung: Diese Plätze werden sofort von wartenden Kunden okkupiert '' -> damit verändert sich auch n.q.Sitzplatz !) let Warteschlangenlaenge = n.q.Sitzplatz(1) if frei > 0 relinquish frei units of Sitzplatz(1) always '' Nun erfolgt die Planung der nächsten Fahrt: if Warteschlangenlaenge < MinAuslastung ''Fall: insgesamt noch zu wenig Fahrgaeste da --> Seilbahn muß warten file Seilbahn in wartende_Seilbahn suspend let frei = 30 - MinAuslastung else '' Genügend Kunden --> Bestimmung der Anzahl der freibleibenden Plätze let frei = 30 - Warteschlangenlaenge if frei < 0 let frei = 0 always always let Auslastung = 30 - frei '' ''list n.x.Sitzplatz(1),n.q.Sitzplatz(1) ''list time.v*minutes.v, Auslastung, Counter '' Sperren der in der nächsten Fahrt freibleibenden Plätze if frei > 0 request frei units of Sitzplatz(1) always '' Statistikvariable aktualisieren let abstand = time.v - letzteFahrt let letzteFahrt = time.v wait 10 Minuten loop end ''Seilbahn process Kunde '' Systemdurchlauf eines individuellen Kunden define stehende_Seilbahn as pointer variable define Ankunftszeit as double variable define in_Bahn_wartender_Kunde as a pointer variable let Ankunftszeit = time.v if n.q.Sitzplatz(1) >= 30 add 1 to ExtraCounter always ''einen Platz anfordern -> Prozess wird automatisch verzoegert! request 1 unit of Sitzplatz(1) if wartende_Seilbahn is not empty if N.X.Sitzplatz(1) = MinAuslastung '' Befoerderungslevel ist erreicht -> die wartende Seilbahn '' wird reaktiviert remove the first stehende_Seilbahn from wartende_Seilbahn reactivate the Seilbahn called stehende_Seilbahn now '' diejenigen Kunden, die nach dem Einsteigen in der Bahn '' warten mußten, werden nun reaktiviert, damit sie zu '' "fahrenden Kunden" werden können while sitzende_Kunden is not empty do remove the first in_Bahn_wartender_Kunde from sitzende_Kunden reactivate this Kunde called in_Bahn_wartender_Kunde now loop else ''Kunde in Warteschlange der sitzenden Kunden einreihen file Kunde in sitzende_Kunden suspend always always let Wartezeit = (time.v - Ankunftszeit) * minutes.v ''list id,Wartezeit * minutes.v ''Seilbahnfahrt file Kunde in fahrende_Kunden suspend relinquish 1 unit of Sitzplatz(1) end ''Kunde process FinalReport define kabinen as a 1-dim real array define I,J as an integer variable reserve kabinen as 4 for J=1 to 3, do let kabinen(j) = 0 for i = 1 to 6 add Warteschlange( 1, 6*(J-1) +I ) to kabinen(J) loop let kabinen(4) = Warteschlange(1,19) skip 3 lines print 2 lines thus Endauswertung ============= skip 1 line print 12 lines with MinAuslastung, time.v, SumKunden, SumFahrten, mittlereAuslastung, mittlererAbstand * minutes.v, ExtraCounter, 100 * ExtraCounter/Counter, mittlereWartezeit and ( time.v - Kabinen(1) ) / time.v * 100 thus Abfahrtslevel : mindestens ** Kunden Simulation endete nach ***.** Stunden -------------------------------------------------- Anzahl der befoerderten Kunden ****** Kunden Anzahl der Seilbahnfahrten *** Fahrten mittlere Auslastung der Seilbahn **.** Kunden mittlerer Abstand der Fahrten **.** Minuten -------------------------------------------------- Anzahl Warteschlange > 30 *** mal ( **.** % ) mittlere Wartezeit eines Kunden **.** Minuten Zeitanteil mit Warteschlange > 30 **.** % skip 3 lines print 4 lines with Warte.Histo(1)/Counter*100 and Warteschlange(1,1)/time.v*100 thus Wartezeitverteilung Warteschlangenlänge =================== =================== T < 2 Min. **.** % Q < 5 **.** % for J = 2 to 18 print 1 line with 2*(J-1), 2* J, Warte.Histo(J)/Counter*100, 5 *(J-1), 5* J, and Warteschlange(1,J)/time.v*100 thus ** <= T < ** Min. **.** % ** <= Q < ** **.** % skip 1 line print 1 line with Warte.Histo(19)/Counter*100 and Warteschlange(1,19)/time.v*100 thus T >= 36 Min. **.** % Q >= 90 **.** % skip 3 lines stop end ''FinalReport