// // ukázka velmi jednoduchého diskrétního simulátoru v C++ // // - popis události je funkce // - kalendář je implementován standardní priority_queue<> // #include <iostream> #include <queue> // priority_queue #include <cstdlib> // exit() using namespace std; ///////////////////////////////////////////////////////////////////////////// // simulátor ///////////////////////////////////////////////////////////////////////////// void error(const char *msg) { cerr << "ERROR: " << msg << endl; exit(1); } typedef void (*event_ptr_t) (); // ukazatel na funkci popisující událost // Aktivační záznam události (pro jednoduchost bez priorit) struct act_record { event_ptr_t event_ptr; // odkaz na událost double atime; // aktivační čas // konstruktor naplní položky: act_record(event_ptr_t e, double at): event_ptr(e), atime(at) {} }; // Porovnání aktivačních záznamů z hlediska jejich pořadí v kalendáři. // Je nutné pro uspořádání kalendáře typu priority_queue<act_record> bool operator <(const act_record & a, const act_record & b) { return a.atime > b.atime; // POZOR HACK // porovnání je obráceně -- lze opravit, ale // musí se použít jiné než implicitní řazení u priority_queue // (menší čas ==> vyšší priorita při řazení) } // Jednoduchý kalendář událostí // - na začátku je vždy aktivační záznam s nejmenším časem priority_queue<act_record> calendar; // Modelový čas double Time; // Plánování události na zadaný čas void schedule(event_ptr_t event_ptr, double at) { cout << "\t\t+Plánování na čas: " << at << endl; if (at < Time) error("Plánování do minulosti"); act_record a(event_ptr, at); calendar.push(a); // zařazení do kalendáře } ///////////////////////////////////////////////////////////////////////////// // Popis modelu ///////////////////////////////////////////////////////////////////////////// void event1() { // popis činnosti cout << "provedení popisu události event1" << endl; schedule(event1, Time + 100); // plánuje další výskyt } void event2() { // popis činnosti cout << "event2" << endl; schedule(event2, Time + 200); // plánuje další výskyt } ///////////////////////////////////////////////////////////////////////////// // Popis simulace ///////////////////////////////////////////////////////////////////////////// const double TSTART = 0; const double TEND = 450; int main() { cout << endl; cout << "=============== inicializace" << endl; // while(!calendar.empty()) calendar.pop(); // inicializace kalendáře Time = TSTART; // inicializace času cout << "Time = " << Time << endl; schedule(event1, Time); // první aktivace schedule(event2, Time); // první aktivace cout << endl; cout << "=============== začátek simulace: čas = " << Time << endl; cout << endl; while (!calendar.empty()) { act_record a = calendar.top(); // přečteme první záznam calendar.pop(); // odstraníme první záznam if (a.atime > TEND) { Time = TEND; break; // končíme simulaci } Time = a.atime; // posuneme čas cout << "[Time = " << Time << "]: \t"; a.event_ptr(); // provedeme událost } cout << endl; cout << "=============== konec simulace: čas = " << Time << endl; cout << endl; }