Wojskowa Akademia Techniczna
im. Jarosława Dąbrowskiego
Sprawozdanie z projektu
Przedmiot: Podstawy Symulacji
Prowadzący: dr inż. Jarosław Rulka
Wykonał: Sobieraj Kamil
Grupa: I1G3S1
Treść zadania:
Napisać program symulujący działanie sieci SMO jak na rysunku:
Przy realizacji zadania należy przyjąć następujące dane z listy przedstawionej poniżej:
rozkład zmiennych Tj: (nrDz + i) mod 6 + 1;
rozkład zmiennych Oi: (nrDz + i + 1) mod 6 + 1;
Li: (nrDz + i) mod 2 + 1;
ALi: (nrDz + i + 2) mod 3 + 1;
Rj = (nrDz + i + 5) mod 3 + 1;
Mi = (nrDz + i + 2) mod 4 + 1;
Blokowanie zgłoszeń 1. SMO (zgłoszenie po zakończonej obsłudze, w przypadku braku miejsca w docelowej kolejce, jest przetrzymywane w gnieździe);
Klienci niecierpliwi w SMOi : Ni = (nrDz + i) mod 4 (ograniczony czas oczekiwania na rozpoczęcie obsługi);
Awaryjność kolejki nr i: i = nrDz mod 3 +1 (należy przyjąć wykładnicze rozkłady czasów bezawaryjnej „pracy” kolejki i jej naprawy, elementy kolejki w wyniku awarii są tracone);
Awaryjność gniazda obsługi w 3. SMO (należy przyjąć wykładnicze rozkłady czasów bezawaryjnej „pracy” gniazda i jego naprawy, zgłoszenie w wyniku awarii musi być ponownie obsłużone);
gdzie:
i - numer SMO;
j - numer strumienia;
Tj - zmienna losowa oznaczająca czas pomiędzy kolejnymi napływami zgłoszeń do systemu;
Oi - zmienna losowa oznaczająca czas obsługi pojedynczego zgłoszenia w gnieździe;
Ni - zmienna losowa oznaczająca czas niecierpliwości zgłoszenia (gdy i = 0 => zgłoszenia cierpliwe);
Rj - zmienna losowa oznaczająca wielkość paczki zgłoszeń (wchodzących w tej samej chwili) j-tego strumienia;
pk - prawdopodobieństwa przemieszczenia się zgłoszenia po danym łuku;
Li - długość kolejki i-tego SMO;
AL.i - algorytmy kolejek (w przypadku istnienia kolejki z priorytetami należy przyjąć, że zgłoszenia posiadają priorytety);
Rozkłady zmiennych losowych:
Wykładniczy
Erlanga
Normalny
Jednostajny
Trójkątny
Weibulla
Długości kolejek pojedynczych SMO
ograniczone (możliwe straty)
nieograniczone
Algorytm kolejek:
FIFO
LIFO
Z priorytetami
Liczba stanowisk obsługi w gniazdach (1-M)
Ilość zgłoszeń jednocześnie napływających do systemu (1-R)
Pozostałe dane należy określać na początku symulacji. Dane wejściowe i wyniki odczytywane/zapisywane z/do pliku.
Program powinien działać w trybie z i bez generowania komunikatów w trakcie przebiegu symulacji.
Mój numer na liście to 14
Dane przyjęte do zadania:
T1 - rozkład Jednostajny
O1 - rozkład Trójkątny (2 kanały)
O2 - rozkład Weibulla (3 kanały)
O3 - rozkład Wykładniczy (4 kanały)
AL.1 - Z priorytetami (nieograniczona)
AL.2 - FIFO (ograniczona, możliwe straty)
AL.3 - LIFO (nieograniczona)
2. Sposób rozwiązania zadania.
Generator generuje klientów w odstępie czasu określonym rozkładem jednostajnym do kolejki Priorytetowej (nieograniczonej).
Dla każdego klienta zostaje przypisany priorytet, ID i czas wejścia klienta do systemu. Z pierwszej kolejki klient wchodzi do pierwszego gniazda obsługi, które obsługuje klientów z rozkładem trójkątnym i posiada 2 kanały obsługi. Jest on w tym gnieździe obsługiwany, a potem wychodzi z niego i ma do wyboru 2 drogi: wejść do kolejki FIFO lub wejść do kolejki LIFO.
Po wyborze kolejki FIFO, klient zostaje obsłużony w gnieździe obsługi nr 2 o rozkładzie Weibulla i 3 kanałach obsługi. Klient zostaje obsłużony i znowu ma do wyboru 2 drogi: wrócić do kolejki FIFO albo wyjść z systemu.
Po wyborze kolejki LIFO, klient zostaje obsłużony w gnieździe obsługi nr 3 o rozkładzie wykładniczym i 4 kanałach obsługi. Klient zostaje obsłużony i znowu ma do wyboru 2 drogi: wrócić do kolejki Priorytetowej albo wyjść z systemu.
System przeprowadza symulacje dla określonych przez użytkownika danych takich jak: parametry rozkładów, prawdopodobieństwa przejścia do odpowiednich kolejek, długość kolejki i liczba klientów.
Wszystkie charakterystyki graniczne wyznaczane są za pomocą zmiennych monitorowanych odpowiedniego typu np.:
MonCzasSMO1:=GETMONITOR(ASK Gniazdo1 TO CzasWSMO,RStatObj);
MonLiczbaZgloszenSys:=GETMONITOR(ASK System TO LiczbaZgloszen,ITimedStatObj);
Średni czas przebywania klientów w systemie obliczamy za pomocą zmiennych które monitorują dla każdego klienta czas wejścia i czas wyjścia z systemu.
Liczba zgłoszeń oznacza liczbę klientów aktualnie znajdujących się w systemie. Liczba zgłoszeń modyfikowana jest przy wejściu klienta do systemu jak również przy wyjściu klienta z systemu. Klienci mogą być niecierpliwi i również wyjść z systemu.
Liczba zgłoszeń w kolejce jest zwiększana gdy klient wchodzi do kolejki, a zmniejszana gdy klient wychodzi z kolejki. Jest ona monitorowana oddzielnie dla danej kolejki.
Prawdopodobieństwo obsłużenia zgłoszenia jest stosunkiem liczby obsłużonych klientów do wszystkich klientów wchodzących do SMO.
Do gromadzenia charakterystyk z symulacji wykorzystane zostały monitory. Umożliwia to wykorzystanie metod: Mean i StdDev do estymacji odpowiedniej wartości średniej i odchylenia standardowego. W momencie wejścia klienta do SMO wywoływana jest metoda CzasWejscia(IN WKlient : KlientObj); która przypisuje na zmienną czasową aktualny czas (za pomocą SimTime).
Użyte rozkłady:
Rozkład wykładniczy:
Gęstość:
Dystrybuanta:
Rozkład trójkątny:
Rozkład jednostajny:
Rozkład Weibulla:
Gęstość:
Dystrybuanta:
4. Kod realizujący zadanie:
MAIN MODULE kamil;
FROM IOMod IMPORT ReadKey, StreamObj, ALL FileUseType; {Output, Input, InOut, Append}
FROM RandMod IMPORT RandomObj, FetchSeed;
FROM SimMod IMPORT StartSimulation, StopSimulation, SimTime, TriggerObj, Interrupt;
FROM StatMod IMPORT SINTEGER, RStatObj, SREAL, TSINTEGER, ITimedStatObj;
FROM GrpMod IMPORT StatQueueObj, StatStackObj, StatRankedObj, BStatGroupObj;
{+++++ Definicje typow (obiektow) +++++}
TYPE
SystemObj = OBJECT; FORWARD;
KlientObj = OBJECT; FORWARD;
GeneratorObj = OBJECT; FORWARD;
KolejkaObj = OBJECT; FORWARD;
GniazdoObj = OBJECT; FORWARD;
{+++++ Deklaracje typow (obiektow) +++++}
{+++++ Deklaracja obiektu systemu +++++++++++++++++++++++++++++++++++++++++++++++++++++++}
SystemObj = OBJECT
CzasPrzebywaniaZgloszenia : SREAL;
LiczbaZgloszen : TSINTEGER;
LiczbaObsluzonych : INTEGER;
LiczbaWygenerowanych : INTEGER;
KomunikatyWlaczone : BOOLEAN;
ASK METHOD Init(IN Komunikaty : BOOLEAN);
ASK METHOD Zwieksz();
ASK METHOD CzasWejscia(IN WKli:KlientObj);
ASK METHOD Wyjscie(IN WKli:KlientObj;IN Obsluzony:BOOLEAN);
END OBJECT;
{+++++ Deklaracja obiektu klienta +++++++++++++++++++++++++++++++++++++++++++++++++++++++}
KlientObj = OBJECT
CzasWejsciaSys : REAL; {czas wejscia klienta do systemu}
CzasWejsciaKol : REAL; {czas wejscia do kolejki - ustawiany przy kazdym kolejnym wejsciu do kolejki}
IDKlienta : INTEGER; {Numer ID identyfikujacy klienta}
Priorytet : INTEGER; {priotytet klienta w kolejce priorytetowej}
KomunikatyWlaczone : BOOLEAN;
ASK METHOD Init(IN WPrior:INTEGER;IN WIDKlienta:INTEGER; IN Komunikaty : BOOLEAN); {inicjalizacja klienta}
ASK METHOD CzasWejscia(IN WSys:INTEGER; IN WKol:INTEGER); {ustawia czas wejscia klienta do systemu lub kolejki}
TELL METHOD Niecierpliwosc(IN WSys: SystemObj; IN WKol:KolejkaObj;IN WCzasCierpliwosci:REAL);
END OBJECT;
{+++++ Deklaracja obiektu generatora ++++++++++++++++++++++++++++++++++++++++++++++++++}
GeneratorObj=OBJECT(RandomObj)
System : SystemObj;
NrRozkladu : INTEGER;
GParametr1 : REAL; {parametry rozkladu z jakim generator ma generować klientów}
GParametr2 : REAL;
GParametr3 : REAL;
Kolejka : KolejkaObj; {kolejka, do której udają się wygenerowani klienci}
LiczbaWygen, MaxLiczbaWygen : INTEGER;
Paczka : INTEGER; {wielkosc paczki zgloszen naplywajacych do systemu}
KomunikatyWlaczone : BOOLEAN;
TriggerGeneratora : TriggerObj;
ASK METHOD Init(IN WSys:SystemObj; IN WNrRoz:INTEGER; IN WGParametr1:REAL; IN WGParametr2:REAL;
IN WGParameter3:REAL; IN WKol:KolejkaObj; IN WMaxWyg:INTEGER; IN WPaczka:INTEGER;
IN Komunikaty : BOOLEAN; IN WtriggerGen : TriggerObj);
TELL METHOD Generuj();
END OBJECT;
{+++++ Deklaracja obiektu kolejki +++++++++++++++++++++++++++++++++++++++++++++++++++++++}
KolejkaObj = OBJECT
System : SystemObj;
Gniazdo : GniazdoObj;
Typ : INTEGER;
Dlugosc : INTEGER;
LiczbaKlientow : TSINTEGER;
Kolejka : BStatGroupObj; {typ kolejkowy}
KomunikatyWlaczone : BOOLEAN;
TriggerGniazda, TriggerGeneratora : TriggerObj;
ASK METHOD Init(IN WSys:SystemObj; IN WGniazdo:GniazdoObj; IN WTyp:INTEGER; IN WDlugosc:INTEGER;
IN Komunikaty : BOOLEAN; IN WTrigger : TriggerObj; IN WtriggerGen : TriggerObj);
ASK METHOD Dodaj(IN WSys:SystemObj;IN WKl:KlientObj);
ASK METHOD Usun(IN WKl:KlientObj):KlientObj;
END OBJECT;
{+++++ Deklaracja obiektu gniazdq ++++++++++++++++++++++++++++++++++++++++++++++++++++++}
GniazdoObj = OBJECT
RandomGen : RandomObj; {generator rozkladow dla gniazda}
System : SystemObj;
TypRozkladu : INTEGER;
Obslugiwany : KlientObj;
CzasWSMO : SREAL;
IloscStanowisk, IloscZajetych : TSINTEGER;
KolejkaWY, KolejkaWE : KolejkaObj;
Pstwo : REAL; {prawdopodobienstwo powrotu do gniazda}
Parametr1, Parametr2, Parametr3 : REAL;
KomunikatyWlaczone : BOOLEAN;
TriggerGniazda : TriggerObj;
TriggerGeneratora : TriggerObj;
Pracuj : BOOLEAN;
ASK METHOD Init(IN WSeed:INTEGER;IN WSys:SystemObj; IN WTypRozkl:INTEGER; IN WIloscStanowisk:INTEGER;
IN WKolejkaWY:KolejkaObj; IN WKolejkaWE:KolejkaObj; IN WParametr1:REAL; IN WParametr2:REAL;
IN WParametr3:REAL; IN WPrawdopodPowr:REAL; IN Komunikaty : BOOLEAN; IN WTrigger : TriggerObj;
IN WTrigger2 : TriggerObj);
TELL METHOD Obsluguj();
TELL METHOD Koniec();
END OBJECT;
{+++++ Deklaracja obiektu kolejki priorytetowej +++++++++++++++++++++++++++++++++++}
KolPriorObj = OBJECT(StatRankedObj)
OVERRIDE
ASK METHOD Rank(IN WKl1 : ANYOBJ; IN WKl2 : ANYOBJ) : INTEGER;
END OBJECT;
{+++++ Obiekt Kolejki ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
OBJECT KolejkaObj;
ASK METHOD Init(IN WSys:SystemObj;IN WGniazdo:GniazdoObj;IN WTyp:INTEGER; IN WDlugosc:INTEGER;
IN Komunikaty : BOOLEAN; IN WTrigger : TriggerObj; IN WTriggerGen : TriggerObj);
VAR
KolejkaLIFO : StatStackObj;
KolejkaPrior : KolPriorObj;
KolejkaFIFO : StatQueueObj;
BEGIN
System := WSys;
Gniazdo := WGniazdo;
Typ := WTyp;
LiczbaKlientow := 0;
Dlugosc := WDlugosc;
KomunikatyWlaczone := Komunikaty;
TriggerGniazda := WTrigger;
TriggerGeneratora := WTriggerGen;
CASE WTyp
WHEN 1:
NEW(KolejkaPrior); Kolejka := KolejkaPrior;
WHEN 2:
NEW(KolejkaFIFO); Kolejka := KolejkaFIFO;
WHEN 3:
NEW(KolejkaLIFO); Kolejka := KolejkaLIFO;
END CASE;
END METHOD;
{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
ASK METHOD Dodaj(IN WSys:SystemObj;IN WKlient:KlientObj);
VAR
CzasCierpliwosci : REAL;
BEGIN
CASE ASK SELF TO Typ
WHEN 1:
CzasCierpliwosci := 3.0;
WHEN 2:
CzasCierpliwosci := 0.0;
WHEN 3:
CzasCierpliwosci := 1.0;
END CASE;
IF Dlugosc > 0 {dlugosc kolejki, 0- nieograniczona}
IF LiczbaKlientow < Dlugosc
ASK WKlient TO CzasWejscia(0,1);
ASK Kolejka TO Add(WKlient); {wejscie klienta do kolejki}
TELL WKlient TO Niecierpliwosc (WSys,SELF, CzasCierpliwosci); {wlaczenie niecierpliwosci klienta}
IF (KomunikatyWlaczone)
OUTPUT("Klient",ASK WKlient TO IDKlienta," wchodzi do Gniazda ",ASK SELF TO Typ);
END IF;
INC(LiczbaKlientow); {zwiekszenie liczby klientów w kolejce}
ASK TriggerGniazda TO Release;
ELSE
IF (KomunikatyWlaczone)
OUTPUT("Klient",ASK WKlient TO IDKlienta," nie mogl wejsc do przepelnionej kolejki Gniazda ",ASK SELF TO Typ);
END IF;
ASK System TO Wyjscie(WKlient,FALSE);
END IF;
ELSE
ASK WKlient TO CzasWejscia(0,1);
ASK Kolejka TO Add(WKlient);
IF (KomunikatyWlaczone)
OUTPUT("Klient",ASK WKlient TO IDKlienta," wchodzi do kolejki ");
END IF;
INC(LiczbaKlientow);
ASK TriggerGniazda TO Release;
END IF;
END METHOD;
{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
ASK METHOD Usun(IN WKlient:KlientObj):KlientObj; {usuwanie klienta z kolejki}
VAR
PomKlient : KlientObj;
BEGIN
IF LiczbaKlientow > 0
IF WKlient = NILOBJ
PomKlient:=ASK Kolejka TO Remove();
IF (KomunikatyWlaczone)
OUTPUT("Gniazdo",ASK SELF TO Typ," wychodzi Klient",ASK PomKlient TO IDKlienta);
END IF;
ELSE
ASK Kolejka TO RemoveThis(WKlient);
PomKlient:=WKlient;
END IF;
DEC(LiczbaKlientow);
IF (TriggerGeneratora <> NILOBJ)
ASK TriggerGeneratora TO Release();
END IF;
RETURN PomKlient;
ELSE
RETURN NILOBJ;
END IF;
END METHOD;
END OBJECT;
{+++++ Obiekt Klienta ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
OBJECT KlientObj;
ASK METHOD Init(IN WPrior:INTEGER; IN WIDKlienta:INTEGER; IN Komunikaty : BOOLEAN);
BEGIN
CzasWejsciaSys := 0.0;
CzasWejsciaKol := 0.0;
Priorytet := WPrior;
IDKlienta := WIDKlienta;
KomunikatyWlaczone := Komunikaty;
IF (KomunikatyWlaczone)
OUTPUT("Generator wygenerowal Klienta",ASK SELF TO IDKlienta);
END IF;
END METHOD;
{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
ASK METHOD CzasWejscia(IN WSys:INTEGER;IN WKol:INTEGER); {ustawienie czasu wejścia do systemu lub kolejki}
BEGIN
IF WSys = 1
CzasWejsciaSys := SimTime;
END IF;
IF WKol = 1
CzasWejsciaKol := SimTime;
END IF;
END METHOD;
TELL METHOD Niecierpliwosc(IN WSys: SystemObj; IN WKol:KolejkaObj; IN WCzasCierpliwosci:REAL);
VAR
pom:KlientObj;
BEGIN
IF WCzasCierpliwosci > 0.0;
WAIT DURATION WCzasCierpliwosci;
pom := ASK WKol TO Usun(SELF);
IF (KomunikatyWlaczone)
OUTPUT("Klient",ASK SELF TO IDKlienta," stracil cierpliwosc.");
END IF;
ASK WSys TO Wyjscie(SELF, FALSE);
ON INTERRUPT;
END WAIT;
END IF;
END METHOD;
END OBJECT;
{+++++ Obiekt Generatora Klientow +++++++++++++++++++++++++++++++++++++++++++++++++++++++}
OBJECT GeneratorObj;
ASK METHOD Init(IN WSys : SystemObj; IN WNrRoz:INTEGER; IN WG1:REAL; IN WG2:REAL; IN WG3:REAL;
IN WKol:KolejkaObj; IN WMaxWyg:INTEGER; IN WPaczka:INTEGER; IN Komunikaty : BOOLEAN;
IN WTriggerGen : TriggerObj);
BEGIN
GParametr1 := WG1;
GParametr2 := WG2;
GParametr3 := WG3;
Kolejka := WKol;
LiczbaWygen := 1;
NrRozkladu := WNrRoz;
MaxLiczbaWygen := WMaxWyg;
Paczka:= WPaczka;
System := WSys;
KomunikatyWlaczone := Komunikaty;
TriggerGeneratora := WTriggerGen;
END METHOD;
{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
TELL METHOD Generuj();
VAR
Czas : REAL;
Prior, PaczkaZgloszen, i : INTEGER;
Klient : KlientObj;
BEGIN
WHILE LiczbaWygen < MaxLiczbaWygen
Prior := ASK SELF TO UniformInt(1,10); {losowanie priorytetu klienta}
PaczkaZgloszen:= ASK SELF TO UniformInt (1,Paczka);
Czas := ASK SELF TO UniformReal(GParametr1, GParametr2);
IF Czas<0.0
Czas:=ABS(Czas);
END IF;
WAIT DURATION Czas
END WAIT;
FOR i:=1 TO Paczka
NEW(Klient);
IF (KomunikatyWlaczone)
OUTPUT ("Generator generuje Klienta ");
END IF;
ASK System TO Zwieksz();
ASK Klient TO Init(Prior, ASK System TO LiczbaWygenerowanych, KomunikatyWlaczone);
ASK System TO CzasWejscia(Klient);
ASK Kolejka TO Dodaj(System, Klient);
INC(LiczbaWygen);
END FOR;
END WHILE;
END METHOD;
END OBJECT;
{+++++ Obiekt Modelowanego Systemu +++++++++++++++++++++++++++++++++++++++++++++++++++++++}
OBJECT SystemObj;
ASK METHOD Init(IN Komunikaty : BOOLEAN);
BEGIN
CzasPrzebywaniaZgloszenia := 0.0;
LiczbaZgloszen := 0;
LiczbaObsluzonych := 0;
LiczbaWygenerowanych := 0;
KomunikatyWlaczone := Komunikaty;
END METHOD;
{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
ASK METHOD CzasWejscia(IN WKlient : KlientObj);
BEGIN
ASK WKlient TO CzasWejscia(1,0); {ustawienie czasu wejscia klienta do systemu na SimTime}
INC(LiczbaZgloszen);
END METHOD;
{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
ASK METHOD Wyjscie(IN WKlient:KlientObj; IN Obsluzony:BOOLEAN);
BEGIN
CzasPrzebywaniaZgloszenia := (SimTime - (ASK WKlient TO CzasWejsciaSys));
IF Obsluzony
INC(LiczbaObsluzonych);
IF (KomunikatyWlaczone)
OUTPUT("Klient", ASK WKlient TO IDKlienta," opuscil system");
OUTPUT("Liczba obsluzonych: ",ASK SELF TO LiczbaObsluzonych);
END IF;
ELSE
IF (KomunikatyWlaczone)
OUTPUT("Klient", ASK WKlient TO IDKlienta," nie opuscil systemu");
END IF;
END IF;
DEC(LiczbaZgloszen);
END METHOD;
ASK METHOD Zwieksz();
BEGIN
INC(LiczbaWygenerowanych);
END METHOD;
END OBJECT;
{+++++ Obiekt Gniazda ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
OBJECT GniazdoObj;
ASK METHOD Init(IN WSeed : INTEGER; IN WSystem : SystemObj;
IN WTypRozkl : INTEGER; IN WIloscStanowisk : INTEGER;
IN WKolejkaWY : KolejkaObj; IN WKolejkaWE : KolejkaObj;
IN WParametr1 : REAL; IN WParametr2 : REAL; IN WParametr3 : REAL;
IN WPrawdopodPowr : REAL; IN Komunikaty : BOOLEAN; IN WTrigger : TriggerObj;
IN WTrigger2 : TriggerObj);
VAR
Tmp : INTEGER;
BEGIN
System := WSystem;
TypRozkladu := WTypRozkl;
IloscStanowisk := WIloscStanowisk;
KolejkaWY := WKolejkaWY;
KolejkaWE := WKolejkaWE;
Pstwo := WPrawdopodPowr;
Parametr1 := WParametr1;
Parametr2 := WParametr2;
Parametr3 := WParametr3;
IloscZajetych := 0;
CzasWSMO := 0.0;
NEW(RandomGen);
ASK RandomGen TO SetSeed(WSeed);
KomunikatyWlaczone := Komunikaty;
TriggerGniazda := WTrigger;
TriggerGeneratora := WTrigger2;
FOR Tmp:=0 TO IloscStanowisk-1
TELL SELF TO Obsluguj();
END FOR;
END METHOD;
{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
TELL METHOD Obsluguj();
VAR
Czas : REAL;
BEGIN
Pracuj := TRUE;
WHILE (Pracuj)
WAIT FOR TriggerGniazda TO Fire;
ON INTERRUPT
END WAIT;
WHILE (((ASK KolejkaWE TO LiczbaKlientow) > 0) AND (IloscStanowisk > IloscZajetych))
INC(IloscZajetych);
CASE TypRozkladu
WHEN 4:
Czas := ASK RandomGen TO Triangular(Parametr1, Parametr2, Parametr3);
WHEN 5:
Czas := ASK RandomGen TO Weibull(Parametr1,Parametr2);
WHEN 6:
Czas := ASK RandomGen TO Exponential(Parametr1);
END CASE;
Obslugiwany := ASK KolejkaWE TO Usun(NILOBJ);
Interrupt(Obslugiwany, "Niecierpliwosc");
WAIT DURATION ABS(Czas);
END WAIT;
CzasWSMO := SimTime - (ASK Obslugiwany TO CzasWejsciaKol);
IF ASK SELF TO TypRozkladu=5;
IF ASK RandomGen TO Sample() > Pstwo;
IF (KomunikatyWlaczone)
OUTPUT("Gniazdo ",ASK SELF TO TypRozkladu-3," opuszcza Klient",
ASK Obslugiwany TO IDKlienta);
END IF;
ASK System TO Wyjscie(Obslugiwany, TRUE);
DEC(IloscZajetych);
ELSE
IF (KomunikatyWlaczone)
OUTPUT("Klient", ASK Obslugiwany TO IDKlienta," wraca do Gniazda",
ASK SELF TO TypRozkladu-3,".");
END IF;
ASK KolejkaWE TO Dodaj(System, Obslugiwany);
END IF;
END IF;
IF ASK SELF TO TypRozkladu=6;
IF ASK RandomGen TO Sample() > Pstwo;
IF (KomunikatyWlaczone)
OUTPUT("Gniazdo ",ASK SELF TO TypRozkladu-3," opuszcza Klient",
ASK Obslugiwany TO IDKlienta);
END IF;
ASK System TO Wyjscie(Obslugiwany, TRUE);
DEC(IloscZajetych);
ELSE
IF (KomunikatyWlaczone)
OUTPUT("Klient", ASK Obslugiwany TO IDKlienta," wraca do Gniazda",
ASK SELF TO TypRozkladu-3,".");
END IF;
ASK KolejkaWE TO Dodaj(System, Obslugiwany);
END IF;
END IF;
IF ASK SELF TO TypRozkladu=4;
IF ASK RandomGen TO Sample() > Pstwo;
IF (KomunikatyWlaczone)
OUTPUT("Gniazdo 1 opuszcza Klient",ASK Obslugiwany TO IDKlienta);
END IF;
IF (TriggerGeneratora <> NILOBJ)
IF (ASK KolejkaWY TO LiczbaKlientow = ASK KolejkaWY TO Dlugosc)
IF (KomunikatyWlaczone)
OUTPUT ("Gniazdo zablokowane.");
END IF;
WAIT FOR TriggerGeneratora TO Fire();
END WAIT;
END IF;
END IF;
ASK KolejkaWY TO Dodaj(System, Obslugiwany);
{DEC(IloscZajetych);}
ELSE
IF (KomunikatyWlaczone)
OUTPUT("Klient", ASK Obslugiwany TO IDKlienta," idzie do Gniazda",
ASK SELF TO TypRozkladu-3,".");
END IF;
ASK KolejkaWE TO Dodaj(System, Obslugiwany);
END IF;
END IF;
END WHILE;
END WHILE;
END METHOD;
{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
TELL METHOD Koniec();
VAR
Tmp : INTEGER;
BEGIN
Pracuj := FALSE;
WAIT DURATION 0.0
ASK TriggerGniazda TO InterruptTrigger;
END WAIT;
END METHOD;
END OBJECT;
{+++++ Obiekt Kolejki ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
OBJECT KolPriorObj;
ASK METHOD Rank(IN a,b : ANYOBJ) : INTEGER; {Porownywanie priorytetow dwoch klientow}
VAR
Klient1 : KlientObj;
Klient2 : KlientObj;
BEGIN
Klient1 := a;
Klient2 := b;
IF ASK Klient1 TO Priorytet < ASK Klient2 TO Priorytet
RETURN -1;
END IF;
IF ASK Klient1 TO Priorytet > ASK Klient2 TO Priorytet
RETURN 1;
END IF;
RETURN 0;
END METHOD;
END OBJECT;
{+++++ Czesc glowna symulatora +++++}
VAR
System : SystemObj;
Generator1 : GeneratorObj;
Gniazdo1, Gniazdo2, Gniazdo3 : GniazdoObj;
KolejkaLIFO, KolejkaPrior, KolejkaFIFO : KolejkaObj;
{+++++ Deklaracje zmiennych ++++++++++}
P1, P2, P3, Gen1Lo, Gen1Hi, Gniazdo1Min,
Gniazdo1Mean, Gniazdo1Max, Gniazdo2Shape, Gniazdo2Scale,
Gniazdo3Mean, PrawdopodObsluzenia : REAL;
DlugoscKol2, MaxWygen, Gen1Seed : INTEGER;
Klient : KlientObj;
MonCzas, MonCzasSMO1, MonCzasSMO2, MonCzasSMO3 : RStatObj;
MonLiczbaZgloszenSys, MonLiczbaZajetychGn1, MonLiczbaZajetychGn2,
MonLiczbaZajetychGn3, MonZgloszenWKolejce1, MonZgloszenWKolejce2,
MonZgloszenWKolejce3 : ITimedStatObj;
TriggerG1, TriggerG2, TriggerG3, TriggerBlokujacy : TriggerObj;
Key : CHAR;
Plik : StreamObj;
Tekst : STRING;
Komunikaty : BOOLEAN;
Zpliku : BOOLEAN;
BEGIN
{+++++ Pobranie parametrow symulacji ++++++++++++++++++++++++++++++++++++++++++++++++++}
OUTPUT("Czy pokazywac komunikaty? [T/N]: ");
Key := ReadKey();
OUTPUT("");
Komunikaty := TRUE;
IF ((Key = 'n') OR (Key = 'N'))
Komunikaty := FALSE;
END IF;
IF ((Key = 't') OR (Key = 'T'))
Komunikaty := TRUE;
END IF;
OUTPUT("Czy wczytac dane z pliku? [T/N]: ");
Key := ReadKey();
OUTPUT("");
Zpliku := TRUE;
IF ((Key = 'n') OR (Key = 'N'))
Zpliku:= FALSE;
END IF;
IF ((Key = 't') OR (Key = 'T'))
Zpliku := TRUE;
END IF;
NEW(Plik);
IF Zpliku = TRUE;
ASK Plik TO Open("parametry.txt",Input);
{Parametry generatora pierwszego T1}
ASK Plik TO ReadLine(Tekst);
ASK Plik TO ReadReal(Gen1Lo); ASK Plik TO ReadLine(Tekst);
ASK Plik TO ReadReal(Gen1Hi); ASK Plik TO ReadLine(Tekst);
ASK Plik TO ReadInt(Gen1Seed); ASK Plik TO ReadLine(Tekst);
{Parametry gniazda pierwszego O1}
ASK Plik TO ReadLine(Tekst);
ASK Plik TO ReadReal(Gniazdo1Min); ASK Plik TO ReadLine(Tekst);
ASK Plik TO ReadReal(Gniazdo1Mean); ASK Plik TO ReadLine(Tekst);
ASK Plik TO ReadReal(Gniazdo1Max); ASK Plik TO ReadLine(Tekst);
{Parametry gniazda pierwszego O2}
ASK Plik TO ReadLine(Tekst);
ASK Plik TO ReadReal(Gniazdo2Shape); ASK Plik TO ReadLine(Tekst);
ASK Plik TO ReadReal(Gniazdo2Scale); ASK Plik TO ReadLine(Tekst);
{Parametry gniazda pierwszego O3}
ASK Plik TO ReadLine(Tekst);
ASK Plik TO ReadReal(Gniazdo3Mean); ASK Plik TO ReadLine(Tekst);
{Dlugosc kolejki Priorytetowej}
ASK Plik TO ReadLine(Tekst);
ASK Plik TO ReadInt(DlugoscKol2); ASK Plik TO ReadLine(Tekst);
{Ilosc klientow, ktora ma wygenerowac kazdy z generatorow}
ASK Plik TO ReadLine(Tekst);
ASK Plik TO ReadInt(MaxWygen); ASK Plik TO ReadLine(Tekst);
{Prawdopodobienstwo powrotu klienta do gniazda O1}
ASK Plik TO ReadLine(Tekst);
ASK Plik TO ReadReal(P1); ASK Plik TO ReadLine(Tekst);
{Prawdopodobienstwo powrotu klienta do gniazda O2}
ASK Plik TO ReadLine(Tekst);
ASK Plik TO ReadReal(P2); ASK Plik TO ReadLine(Tekst);
{Prawdopodobienstwo powrotu klienta do gniazda O3}
ASK Plik TO ReadLine(Tekst);
ASK Plik TO ReadReal(P3); ASK Plik TO ReadLine(Tekst);
ASK Plik TO Close();
ELSE
{Parametry generatora pierwszego T1}
Gen1Lo:=1.2;
Gen1Hi:=5.6;
Gen1Seed:=3;
{Parametry gniazda pierwszego O1}
Gniazdo1Min:=2.3;
Gniazdo1Mean:=4.3;
Gniazdo1Max:=5.6;
{Parametry gniazda pierwszego O2}
Gniazdo2Shape:=3.5;
Gniazdo2Scale:=7.8;
{Parametry gniazda pierwszego O3}
Gniazdo3Mean:=4.6;
{Dlugosc kolejki Priorytetowej}
DlugoscKol2:=5;
{Ilosc klientow, ktora ma wygenerowac kazdy z generatorow}
MaxWygen:=10;
{Prawdopodobienstwo powrotu klienta do gniazda O1}
P1:=0.1;
{Prawdopodobienstwo powrotu klienta do gniazda O2}
P2:=0.1;
{Prawdopodobienstwo powrotu klienta do gniazda O3}
P3:=0.1;
END IF;
DISPOSE(Plik);
OUTPUT(" ");
OUTPUT("SYMULACJA:");
OUTPUT(" ");
{+++++ Tworzenie obiektow +++++++++++++++}
NEW(System);
NEW(Gniazdo1);
NEW(Gniazdo2);
NEW(Gniazdo3);
NEW(KolejkaLIFO);
NEW(KolejkaPrior);
NEW(KolejkaFIFO);
NEW(Generator1);
NEW(TriggerG1);
NEW(TriggerG2);
NEW(TriggerG3);
NEW(TriggerBlokujacy);
{+++++ Inicjalizacja obiektow ++++++++++}
ASK System TO Init(Komunikaty);
ASK KolejkaPrior TO Init (System, Gniazdo1, 1, 0, Komunikaty, TriggerG1, TriggerBlokujacy);
ASK KolejkaFIFO TO Init (System, Gniazdo2, 2, DlugoscKol2, Komunikaty, TriggerG2, NILOBJ);
ASK KolejkaLIFO TO Init (System, Gniazdo3, 3, 0, Komunikaty, TriggerG3, NILOBJ);
ASK Generator1 TO SetSeed(Gen1Seed);
ASK Generator1 TO Init(System, 3, Gen1Lo, Gen1Hi, 0.0, KolejkaPrior, MaxWygen, 3, Komunikaty, NILOBJ);
ASK Gniazdo1 TO Init(1, System, 4, 2, KolejkaFIFO, KolejkaLIFO, Gniazdo1Min, Gniazdo1Mean, Gniazdo1Max, P1, Komunikaty, TriggerG1, TriggerBlokujacy);
ASK Gniazdo2 TO Init(1, System, 5, 3, NILOBJ, KolejkaFIFO, Gniazdo2Shape, Gniazdo2Scale, 0.0, P2, Komunikaty, TriggerG2, NILOBJ);
ASK Gniazdo3 TO Init(1, System, 6, 4, NILOBJ, KolejkaPrior, Gniazdo3Mean, 0.0, 0.0, P3, Komunikaty, TriggerG3, NILOBJ);
{+++++ Symulacja +++++++++++++++++++++++++}
TELL Generator1 TO Generuj();
StartSimulation();
TELL Gniazdo1 TO Koniec();
TELL Gniazdo2 TO Koniec();
TELL Gniazdo3 TO Koniec();
StartSimulation;
{+++++ Pobieranie monitorow zmiennych ++++++++++++++++++++++++++++++++++++++++++++++++++}
MonCzas := GETMONITOR(ASK System TO CzasPrzebywaniaZgloszenia,RStatObj);
MonCzasSMO1 := GETMONITOR(ASK Gniazdo1 TO CzasWSMO,RStatObj);
MonCzasSMO2 := GETMONITOR(ASK Gniazdo2 TO CzasWSMO,RStatObj);
MonCzasSMO3 := GETMONITOR(ASK Gniazdo3 TO CzasWSMO,RStatObj);
MonLiczbaZgloszenSys := GETMONITOR(ASK System TO LiczbaZgloszen,ITimedStatObj);
MonLiczbaZajetychGn1 := GETMONITOR(ASK Gniazdo1 TO IloscZajetych,ITimedStatObj);
MonLiczbaZajetychGn2 := GETMONITOR(ASK Gniazdo2 TO IloscZajetych,ITimedStatObj);
MonLiczbaZajetychGn3 := GETMONITOR(ASK Gniazdo3 TO IloscZajetych,ITimedStatObj);
MonZgloszenWKolejce1 := GETMONITOR(ASK KolejkaPrior TO LiczbaKlientow,ITimedStatObj);
MonZgloszenWKolejce2 := GETMONITOR(ASK KolejkaFIFO TO LiczbaKlientow,ITimedStatObj);
MonZgloszenWKolejce3 := GETMONITOR(ASK KolejkaLIFO TO LiczbaKlientow,ITimedStatObj);
PrawdopodObsluzenia := FLOAT(ASK System TO LiczbaObsluzonych)/FLOAT(ASK System TO LiczbaWygenerowanych);
{+++++ Zapis wynikow symulacji do pliku +++++++++++++++++++++++++++++++++++++++++++++}
NEW(Plik);
ASK Plik TO Open("wyniki.txt",Output);
ASK Plik TO WriteString("WYNIKI DZIALANIA SYMULACJI: ");ASK Plik TO WriteLn();
ASK Plik TO WriteLn();
ASK Plik TO WriteString("Czas przebywania zgloszenia w systemie:");ASK Plik TO WriteLn();
ASK Plik TO WriteString( SPRINT(ASK MonCzas TO Mean) WITH " Wartosc srednia: ***.*** ");ASK Plik TO WriteLn();
ASK Plik TO WriteString( SPRINT(ASK MonCzas TO StdDev) WITH " Odchylenie standardowe: ***.***");ASK Plik TO WriteLn();
ASK Plik TO WriteLn();
ASK Plik TO WriteString("Czas przebywania zgloszenia w SMO1:");ASK Plik TO WriteLn();
ASK Plik TO WriteString( SPRINT(ASK MonCzasSMO1 TO Mean) WITH " Wartosc srednia: ***.***");ASK Plik TO WriteLn();
ASK Plik TO WriteString( SPRINT(ASK MonCzasSMO1 TO StdDev) WITH " Odchylenie standardowe: ***.***");ASK Plik TO WriteLn();
ASK Plik TO WriteLn();
ASK Plik TO WriteString("Czas przebywania zgloszenia w SMO2:");ASK Plik TO WriteLn();
ASK Plik TO WriteString( SPRINT(ASK MonCzasSMO2 TO Mean) WITH " Wartosc srednia: ***.*** ");ASK Plik TO WriteLn();
ASK Plik TO WriteString( SPRINT(ASK MonCzasSMO2 TO StdDev) WITH " Odchylenie standardowe: ***.***");ASK Plik TO WriteLn();
ASK Plik TO WriteLn();
ASK Plik TO WriteString("Czas przebywania zgloszenia w SMO3:");ASK Plik TO WriteLn();
ASK Plik TO WriteString( SPRINT(ASK MonCzasSMO3 TO Mean) WITH " Wartosc srednia: ***.***");ASK Plik TO WriteLn();
ASK Plik TO WriteString( SPRINT(ASK MonCzasSMO3 TO StdDev) WITH " Odchylenie standardowe: ***.***");ASK Plik TO WriteLn();
ASK Plik TO WriteLn();
ASK Plik TO WriteString("Liczba klientow w systemie: ");ASK Plik TO WriteLn();
ASK Plik TO WriteString( SPRINT(ASK MonLiczbaZgloszenSys TO Mean) WITH " Wartosc srednia: ****.***");ASK Plik TO WriteLn();
ASK Plik TO WriteString( SPRINT(ASK MonLiczbaZgloszenSys TO StdDev) WITH " Odchylenie standardowe: ***.***");ASK Plik TO WriteLn();
ASK Plik TO WriteLn();
ASK Plik TO WriteString("Liczba kanalow zajetych w gniezdzie O1:");ASK Plik TO WriteLn();
ASK Plik TO WriteString( SPRINT(ASK MonLiczbaZajetychGn1 TO Mean) WITH " Wartosc srednia: ***.*** ");ASK Plik TO WriteLn();
ASK Plik TO WriteString( SPRINT(ASK MonLiczbaZajetychGn1 TO StdDev) WITH " Odchylenie standardowe: ***.***");ASK Plik TO WriteLn();
ASK Plik TO WriteLn();
ASK Plik TO WriteString("Liczba kanalow zajetych w gniezdzie O2:");ASK Plik TO WriteLn();
ASK Plik TO WriteString( SPRINT(ASK MonLiczbaZajetychGn2 TO Mean) WITH " Wartosc srednia: ***.***");ASK Plik TO WriteLn();
ASK Plik TO WriteString( SPRINT(ASK MonLiczbaZajetychGn2 TO StdDev) WITH " Odchylenie standardowe: ***.***");ASK Plik TO WriteLn();
ASK Plik TO WriteLn();
ASK Plik TO WriteString("Liczba kanalow zajetych w gniezdzie O3:");ASK Plik TO WriteLn();
ASK Plik TO WriteString( SPRINT(ASK MonLiczbaZajetychGn3 TO Mean) WITH " Wartosc srednia: ***.***");ASK Plik TO WriteLn();
ASK Plik TO WriteString( SPRINT(ASK MonLiczbaZajetychGn3 TO StdDev) WITH " Odchylenie standardowe: ***.***");ASK Plik TO WriteLn();
ASK Plik TO WriteLn();
ASK Plik TO WriteString("Liczba klientow w SMO1 (Priorytetowa):");ASK Plik TO WriteLn();
ASK Plik TO WriteString( SPRINT(ASK MonZgloszenWKolejce1 TO Mean) WITH " Wartosc srednia: ***.***");ASK Plik TO WriteLn();
ASK Plik TO WriteString( SPRINT(ASK MonZgloszenWKolejce1 TO StdDev) WITH " Odchylenie standardowe: ***.***");ASK Plik TO WriteLn();
ASK Plik TO WriteLn();
ASK Plik TO WriteString("Liczba klientow w SMO2 (FIFO):");ASK Plik TO WriteLn();
ASK Plik TO WriteString( SPRINT(ASK MonZgloszenWKolejce2 TO Mean) WITH " Wartosc srednia: ***.***");ASK Plik TO WriteLn();
ASK Plik TO WriteString( SPRINT(ASK MonZgloszenWKolejce2 TO StdDev) WITH " Odchylenie standardowe: ***.***");ASK Plik TO WriteLn();
ASK Plik TO WriteLn();
ASK Plik TO WriteString("Liczba klientow w SMO3 (LIFO):");ASK Plik TO WriteLn();
ASK Plik TO WriteString( SPRINT(ASK MonZgloszenWKolejce3 TO Mean) WITH "Wartosc srednia: ***.***");ASK Plik TO WriteLn();
ASK Plik TO WriteString( SPRINT(ASK MonZgloszenWKolejce3 TO StdDev) WITH " Odchylenie standardowe: ***.***");ASK Plik TO WriteLn();
ASK Plik TO WriteLn();
ASK Plik TO WriteString( SPRINT(PrawdopodObsluzenia) WITH "Prawdopodobienstwo obsluzenia klienta w systemie: ***.***");
DISPOSE(Plik);
{+++++ Zwalnianie obiektow ++++++++++}
DISPOSE(KolejkaLIFO);
DISPOSE(KolejkaPrior);
DISPOSE(KolejkaFIFO);
DISPOSE(Generator1);
DISPOSE(Gniazdo1);
DISPOSE(Gniazdo2);
DISPOSE(Gniazdo3);
DISPOSE(System);
DISPOSE(TriggerG1);
DISPOSE(TriggerG2);
DISPOSE(TriggerG3);
DISPOSE(TriggerBlokujacy);
OUTPUT("");
OUTPUT("Aby zakonczyc dzialanie programu wcisnij dowolny klawisz");
Key := ReadKey();
END MODULE.
SMO
SMO
O2
O3
SMO
O1
T1
p1
1-p1
p2
p3