//////////////////////////////////////////////////////////////////////////// // Model CENTRALA.CPP SIMLIB/C++ // // Příklad simulačního programu - hovory přes centrálu // // Velký podnik má vnitřní telefonní síť se 200 klapkami, spojenou přes // centrálu s 6 telefony s veřejnou sití. Předpokládejme, že požadavky // spojení přicházejí z veřejné sití průměrně po 2 minutách (s exponen- // ciálním rozložením). V případě, že klapka není volná s pravděpodob- // ností 90% si volající počká než se uvolní. Hovor trvá průměrně 7minut. // Současně se uskutečňují vnitřní hovory průměrně po 30 sekund a trvají // průměrně 3 minuty. Přibližně po 10 minutách přijde požadavek na hovor // zevnitř ven, který trvá průměrně 10 minut. Zjistěte průměrné zatížení // centrály a průměrné doby čekání na spojení vnějších // a vnitřních hovorů. // #include "simlib.h" //////////////////////////////////////////////////////////////////////////// // časové konstanty (za jednotku času považujeme 1 minutu) const double DOBA_SIMULACE = 8*60;// 8 hodin // střední doba mezi příchody: const double PRICHOD_VNEJSICH = 2; // vnějších požadavků const double PRICHOD_VNITRNICH = 0.5; // vnitřních požadavků const double PRICHOD_ZEVNITR_VEN = 10; // požadavků zevnitř ven // doby hovoru v jednotlivých případech: const double HOVOR_VNEJSI = 7; const double HOVOR_VNITRNI = 3; const double HOVOR_ZEVNITR_VEN = 10; //////////////////////////////////////////////////////////////////////////// // deklarace globálních objektů const int N_TEL = 200; // počet telefonů Store Centrala("Centrála",6); // centrála - kapacita 6 spojení najednou Facility Telefon[N_TEL]; // telefony Histogram Tabulka1("Čekaní na spojení: vnitřní požadavky",0,0.1,20); Histogram Tabulka2("Čekaní na spojení: vnější požadavky",0,0.1,20); // náhodný výběr telefonu (rovnoměrné rozdělení) int RandomTel() { return int(N_TEL*Random()); // 0 .. N_TEL-1 } //////////////////////////////////////////////////////////////////////////// // třídy modelující hovory // class Hovor : public Process { protected: double prichod; // doba vstupu požadavku do vnitřní sítě int odkud, kam; // čísla telefonů (-1 == venku) public: Hovor() : prichod(0), odkud(-1), kam(-1) { Activate(); } }; class HovorZvenku : public Hovor { // vnější požadavky void Behavior() { kam = RandomTel(); // komu se volá Enter(Centrala,1); // obsadí jeden z telefonů centrály prichod = Time; // požadavek vstoupil do vnitřní sítě if (!Telefon[kam].Busy() || Random()<0.9) { // případ, že volaný telefon je volný, anebo obsazený ale // volající je ochoten čekat (p=90%). Seize(Telefon[kam]); // obsazení nebo čekání Tabulka2(Time-prichod); // záznam doby čekání do tabulky Wait(Exponential(HOVOR_VNEJSI)); // probíhá hovor Release(Telefon[kam]); // zavěšení telefonu = uvolnění linky } Leave(Centrala,1); // uvolnění jednoho telefonu centrály } //Behavior public: static void Create() { new HovorZvenku; } }; class VnitrniHovor : public Hovor { // hovory uvnitř podniku double prichod; // doba příchodu požadavku void Behavior() { // náhodně vybere volající telefon - 'odkud' (musí být volný) do odkud=RandomTel(); while(Telefon[odkud].Busy()); prichod=Time; Seize(Telefon[odkud]); // zvedne telefon (obsadí vnitřní linku) // náhodně vybere volané číslo telefonu - kam (podmínka: kam!=odkud) do kam=RandomTel(); while(kam==odkud); // vytočí číslo a čeká... Seize(Telefon[kam]); // volaný zvedá telefon Tabulka1(Time-prichod); // záznam doby čekání Wait(Exponential(HOVOR_VNITRNI)); // probíhá hovor Release(Telefon[kam]); // hovor skončil = uvolnění linek Release(Telefon[odkud]); } //Behavior public: static void Create() { new VnitrniHovor; } }; class HovorZevnitrVen : public Hovor { // požadavky na hovory ven void Behavior() { // náhodně vybere volající telefon - 'odkud' (musí být volný) do odkud=RandomTel(); while(Telefon[odkud].Busy()); Seize(Telefon[odkud]); // zvedne telefon (obsadí linku) Enter(Centrala,1); // obsadí jeden z telefonů centrály Wait(Exponential(HOVOR_ZEVNITR_VEN)); // probíhá hovor Leave(Centrala,1); // uvolnění telefonu centrály Release(Telefon[odkud]); // zavěsí telefon = uvolnění linky } //Behavior public: static void Create() { new HovorZevnitrVen; } }; ///////////////////////////////////////////////////////////////////////////// // generátor požadavků // typedef void (*CreatePtr_t)(); // typ ukazatel na statickou metodu class Generator : public Event { // generátor vnějších požadavků CreatePtr_t create; // ukazatel na metodu Create() double dt; // interval mezi vytvořením požadavků void Behavior() { create(); // generování požadavku Activate(Time+Exponential(dt)); // další požadavek } public: Generator(CreatePtr_t p, double _dt) : create(p), dt(_dt) { Activate(); } }; ///////////////////////////////////////////////////////////////////////////// // Experiment // int main() { SetOutput("centrala.out"); _Print(" CENTRALA - model telefonování přes centrálu\n"); Init(0,DOBA_SIMULACE); // inicializace experimentu // aktivace generátorů požadavků new Generator(HovorZvenku::Create, PRICHOD_VNEJSICH); new Generator(VnitrniHovor::Create, PRICHOD_VNITRNICH); new Generator(HovorZevnitrVen::Create, PRICHOD_ZEVNITR_VEN); // simulace Run(); // tisk výsledků Centrala.Output(); Tabulka1.Output(); Tabulka2.Output(); return 0; } // konec