//========================================================= file = h2d1.c ===== //= A simple "straight C" H2/D/1 queue simulation = //============================================================================= //= Notes: 1) This program is adapted from Figure 1.6 in Simulating = //= Computer Systems, Techniqyes and Tools by M. H. MacDougall = //= (1987). = //= 2) The values of SIM_TIME, ARR_TIME, COV, and SERV_TIME need to = //= be set. = //=---------------------------------------------------------------------------= //= Build: gcc h2d1.c -lm, bcc32 h2d1.c, cl h2d1.c = //=---------------------------------------------------------------------------= //= Execute: h2d1 = //=---------------------------------------------------------------------------= //= History: KJC (05/27/99) - Genesis = //============================================================================= //----- Include files --------------------------------------------------------- #include // Needed for printf() #include // Needed for exit() and rand() #include // Needed for log() //----- Constants ------------------------------------------------------------- #define SIM_TIME 1.0e6 // Simulation time #define ARR_TIME 1.25 // Mean time between arrivals #define COV 2.00 // Coefficient of variation for arrivals #define SERV_TIME 1.00 // Mean service time //----- Function prototypes --------------------------------------------------- double hyper(double x, double cov); // Generate hyperexponential RV //===== Main program ========================================================== void main(void) { double end_time = SIM_TIME; // Total time to simulate double Ta = ARR_TIME; // Mean time between arrivals double cov = COV; // CoV of arrivals double Ts = SERV_TIME; // Mean service time double time = 0.0; // Simulation time double t1 = 0.0; // Time for next event #1 (arrival) double t2 = SIM_TIME; // Time for next event #2 (departure) unsigned long int n = 0; // Number of customers in the system unsigned long int c = 0; // Number of service completions double b = 0.0; // Total busy time double s = 0.0; // Area of number of customers in system double tn = time; // Variable for "last event time" double tb; // Variable for "last start of busy time" double x; // Throughput double u; // Utilization double l; // Mean number in the system double w; // Mean residence time // Main simulation loop while (time < end_time) { if (t1 < t2) // *** Event #1 (arrival) { time = t1; s = s + n * (time - tn); // Update area under "s" curve n++; tn = time; // tn = "last event time" for next event t1 = time + hyper(Ta, cov); if (n == 1) { tb = time; // Set "last start of busy time" t2 = time + Ts; } } else // *** Event #2 (departure) { time = t2; s = s + n * (time - tn); // Update area under "s" curve n--; tn = time; // tn = "last event time" for next event c++; // Increment number of completions if (n > 0) t2 = time + Ts; else { t2 = SIM_TIME; b = b + time - tb; // Update busy time sum if empty } } } x = c / time; // Compute throughput rate u = b / time; // Compute server utilization l = s / time; // Compute mean number in system w = l / x; // Compute mean residence or system time // Output results printf("=============================================================== \n"); printf("= *** Results from H2/D/1 Simulation *** = \n"); printf("=============================================================== \n"); printf("= Total simulated time = %3.4f sec \n", end_time); printf("=============================================================== \n"); printf("= INPUTS: \n"); printf("= Mean time between arrivals = %f sec \n", Ta); printf("= CoV for arrivals = %f \n", cov); printf("= Mean service time = %f sec \n", Ts); printf("=============================================================== \n"); printf("= OUTPUTS: \n"); printf("= Number of completions = %ld cust \n", c); printf("= Throughput rate = %f cust/sec \n", x); printf("= Server utilization = %f %% \n", 100.0 * u); printf("= Mean number in system = %f cust \n", l); printf("= Mean residence time = %f sec \n", w); printf("=============================================================== \n"); } //=========================================================================== //= Function to generate hyperexponentially distributed random variables = //= - Input: Mean value of distribution and coefficient of variation = //= - Output: Returns with hyperexponentially distributed rv = //=-------------------------------------------------------------------------= //= Uses Morse's method taken from SMPL from Simulating Computer Systems = //= Systems, Techniques and Tools by M. H. MacDougall (1987) = //=========================================================================== double hyper(double x, double cov) { double p; // Probability value for Morse's method double z1, z2; // Uniform random numbers from 0 to 1 double hyp_value; // Computed exponential value to be returned double temp; // Temporary double value // Pull a uniform random number (0 < z1 < 1) do { z1 = ((double) rand() / RAND_MAX); } while ((z1 == 0) || (z1 == 1)); // Pull another uniform random number (0 < z2 < 1) do { z2 = ((double) rand() / RAND_MAX); } while ((z2 == 0) || (z2 == 1)); // Compute hyperexponential random variable using Morse's method temp = cov*cov; p = 0.5 * (1.0 - sqrt((temp - 1.0) / (temp + 1.0))); if (z1 > p) temp = x / (1.0 - p); else temp = x / p; hyp_value = -0.5 * temp * log(z2); return(hyp_value); }