////////////////////////////////////////////////////////////////////////////
// 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
syntax highlighted by Code2HTML, v. 0.9.1