////////////////////////////////////////////////////////////////////////////
// Model KOSTKY2.CPP              SIMLIB/C++
//
// Příklad simulačního programu - prodejna s Rubikovými kostkami (verze 2)
//
// Do hračkářství přivezli Rubikovy kostky: ráno v 8 hodin 500 kusů
// a odpoledne  v 15  hodin opět  500 kusů.  V hračkářství se otevírá
// v 8 hodin ráno a zavírá se  v 18 hodin večer. Zákazníci přicházeli
// od  8  hodin  průměrně  po  3/4 minuty (s  exponenciálním
// rozložením) a  každý zákazník  koupil jen jednu kostku. Když
// už byly  všechny kostky  vyprodány, zákazníci  se  nevzdali, stáli
// způsobně ve frontě  a čekali, až  přivezou dalších  500 kusů odpo-
// ledne v 15 hodin. Mezitím  ovšem přicházeli noví zákazníci. Určete
// max. délku fronty  a průměrnou  dobu čekání, spočítejte, kolik zá-
// kazníků  odešlo  s nepořízenou, protože vedoucí prodejnu  striktně
// zavřela  v 18 hodin  a nebrala  ohled  na lidi, kteří  už stáli ve
// frontě. Po 18.hodině už další zákazníci nepřicházeli. Doba obsluhy
// je 1 minuta.
//

//#define SIMLIB_DEBUG 1
#include "simlib.h"

// doba simulace :  T_POC - počáteční, T_KON - konečná
const double T_POC =  8.0;  // hodin
const double T_KON = 18.0;  // hodin

// konstanty:
const double T_OBSLUHY  = 1.0/60;    // doba obsluhy zákazníka - 1 minuta
const double T_DODAVKY1 = T_POC;     // čas dodávky kostek - ráno
const double T_DODAVKY2 = 15.0;      // čas dodávky kostek - odpoledne
const double T_PRICH    = 0.75/60;   // průměrný interval příchodu zákazníků 3/4 min

// histogram pro záznam čekacích dob zákazníků
Histogram Tabulka ("Čekací doby zákazníků",0,0.15,20);

unsigned PocZakazniku = 0;   // celkový počet neobsloužených zákazníků

Queue F("Fronta zákazníků");

class Zakaznik : public Process {  // třída zákazníků
  double Prichod;                  // čas příchodu zákazníka
  void Behavior() {                // popis chování
    Prichod = Time;
    PocZakazniku++;
    Into(F);                       // nákup když jsou, jinak čekání
    Passivate();
    // obsluha v obchode
    PocZakazniku--;
    Tabulka(Time - Prichod);       // záznam doby čekání do tabulky
  }
};

class Obchod : public Process {
  int Sklad;
 public:
  Obchod() { Sklad = 0; Activate(); }
  void Behavior() {
    for(;;)
    {
      if(Sklad==0) Passivate();
      WaitUntil(!F.Empty());
      Zakaznik *z = (Zakaznik *)F.GetFirst();
      Wait(T_OBSLUHY);
      z->Activate();
      Sklad--;
    }
  }
  void Dodavka(int ks) {
    Sklad += ks;
    if(Sklad>0) Activate();
  }
  ~Obchod() {    
    Print("Ve skladu zbylo %d kostek\n", Sklad);
  }
};


class Generator : public Event {        // generátor zákazníků
  void Behavior() {                     // popis chování generátoru
    (new Zakaznik)->Activate();         // nový zákazník
    Activate(Time+Exponential(T_PRICH));
  }
};

class Dodavka : public Event {          // dodávka kostek
  Obchod *Kam;
  void Behavior() {
     Kam->Dodavka(500);
     Terminate();
  }
 public:
  Dodavka(Obchod *kam, double kdy) {
    Kam=kam;
    Activate(kdy);
  }
};

////////////////////////////////////////////////////////////////////////////
// experiment
//
int main() {
  SetOutput("kostky2.out");          // nastavení výstupního souboru
  Init(T_POC,T_KON);                 // inicializace experimentu
  Obchod *o = new Obchod;
  new Dodavka(o,T_DODAVKY1);         // inicializace dodávky zboží ráno
  new Dodavka(o,T_DODAVKY2);         // inicializace dodávky zboží odpoledne
  (new Generator)->Activate();       // inicializace generátoru zákazníků
  _Print(" KOSTKY2 - simulace obchodu\n");
  Run();                             // simulace
  Print("\n S nepořízenou odešlo %u zákazníků \n\n", PocZakazniku);
  Tabulka.Output();
  F.Output();
  return 0;
}

// konec


syntax highlighted by Code2HTML, v. 0.9.1