MM1.C
上传用户:aozhi88
上传日期:2022-07-10
资源大小:255k
文件大小:11k
- /* External definitions for single-server queueing system. */
- #include <stdio.h>
- #include <math.h>
- /*#include "lcgrand.h" Header file for random-number generator. */
- #define Q_LIMIT 100 /* Limit on queue length. */
- #define BUSY 1 /* Mnemonics for server's being busy */
- #define IDLE 0 /* and idle. */
- int next_event_type, num_custs_delayed, num_delays_required, num_events,
- num_in_q, server_status;
- float area_num_in_q, area_server_status, mean_interarrival, mean_service,
- sim_time, time_arrival[Q_LIMIT + 1], time_last_event, time_next_event[3],
- total_of_delays;
- FILE *infile, *outfile;
- /* The following 3 declarations are for use of the random-number generator
- lcgrand and the associated functions lcgrandst and lcgrandgt for seed
- management. This file (named lcgrand.h) should be included in any program
- using these functions by executing
- #include "lcgrand.h"
- before referencing the functions. */
- float lcgrand(int stream);
- void lcgrandst(long zset, int stream);
- long lcgrandgt(int stream);
- void initialize(void);
- void timing(void);
- void arrive(void);
- void depart(void);
- void report(void);
- void update_time_avg_stats(void);
- float expon(float mean);
- main() /* Main function. */
- {
- /* Open input and output files. */
- infile = fopen("mm1.in", "r");
- outfile = fopen("mm1.out", "w");
- /* Specify the number of events for the timing function. */
- num_events = 2;
- /* Read input parameters. */
- fscanf(infile, "%f %f %d", &mean_interarrival, &mean_service,
- &num_delays_required);
- /* Write report heading and input parameters. */
- fprintf(outfile, "Single-server queueing systemnn");
- fprintf(outfile, "Mean interarrival time%11.3f minutesnn",
- mean_interarrival);
- fprintf(outfile, "Mean service time%16.3f minutesnn", mean_service);
- fprintf(outfile, "Number of customers%14dnn", num_delays_required);
- /* Initialize the simulation. */
- initialize();
- /* Run the simulation while more delays are still needed. */
- while (num_custs_delayed < num_delays_required) {
- /* Determine the next event. */
- timing();
- /* Update time-average statistical accumulators. */
- update_time_avg_stats();
- /* Invoke the appropriate event function. */
- switch (next_event_type) {
- case 1:
- arrive();
- break;
- case 2:
- depart();
- break;
- }
- }
- /* Invoke the report generator and end the simulation. */
- report();
- fclose(infile);
- fclose(outfile);
- return 0;
- }
- void initialize(void) /* Initialization function. */
- {
- /* Initialize the simulation clock. */
- sim_time = 0.0;
- /* Initialize the state variables. */
- server_status = IDLE;
- num_in_q = 0;
- time_last_event = 0.0;
- /* Initialize the statistical counters. */
- num_custs_delayed = 0;
- total_of_delays = 0.0;
- area_num_in_q = 0.0;
- area_server_status = 0.0;
- /* Initialize event list. Since no customers are present, the departure
- (service completion) event is eliminated from consideration. */
- time_next_event[1] = sim_time + expon(mean_interarrival);
- time_next_event[2] = 1.0e+30;
- }
- void timing(void) /* Timing function. */
- {
- int i;
- float min_time_next_event = 1.0e+29;
- next_event_type = 0;
- /* Determine the event type of the next event to occur. */
- for (i = 1; i <= num_events; ++i)
- if (time_next_event[i] < min_time_next_event) {
- min_time_next_event = time_next_event[i];
- next_event_type = i;
- }
- /* Check to see whether the event list is empty. */
- if (next_event_type == 0) {
- /* The event list is empty, so stop the simulation. */
- fprintf(outfile, "nEvent list empty at time %f", sim_time);
- exit(1);
- }
- /* The event list is not empty, so advance the simulation clock. */
- sim_time = min_time_next_event;
- }
- void arrive(void) /* Arrival event function. */
- {
- float delay;
- /* Schedule next arrival. */
- time_next_event[1] = sim_time + expon(mean_interarrival);
- /* Check to see whether server is busy. */
- if (server_status == BUSY) {
- /* Server is busy, so increment number of customers in queue. */
- ++num_in_q;
- /* Check to see whether an overflow condition exists. */
- if (num_in_q > Q_LIMIT) {
- /* The queue has overflowed, so stop the simulation. */
- fprintf(outfile, "nOverflow of the array time_arrival at");
- fprintf(outfile, " time %f", sim_time);
- exit(2);
- }
- /* There is still room in the queue, so store the time of arrival of the
- arriving customer at the (new) end of time_arrival. */
- time_arrival[num_in_q] = sim_time;
- }
- else {
- /* Server is idle, so arriving customer has a delay of zero. (The
- following two statements are for program clarity and do not affect
- the results of the simulation.) */
- delay = 0.0;
- total_of_delays += delay;
- /* Increment the number of customers delayed, and make server busy. */
- ++num_custs_delayed;
- server_status = BUSY;
- /* Schedule a departure (service completion). */
- time_next_event[2] = sim_time + expon(mean_service);
- }
- }
- void depart(void) /* Departure event function. */
- {
- int i;
- float delay;
- /* Check to see whether the queue is empty. */
- if (num_in_q == 0) {
- /* The queue is empty so make the server idle and eliminate the
- departure (service completion) event from consideration. */
- server_status = IDLE;
- time_next_event[2] = 1.0e+30;
- }
- else {
- /* The queue is nonempty, so decrement the number of customers in
- queue. */
- --num_in_q;
- /* Compute the delay of the customer who is beginning service and update
- the total delay accumulator. */
- delay = sim_time - time_arrival[1];
- total_of_delays += delay;
- /* Increment the number of customers delayed, and schedule departure. */
- ++num_custs_delayed;
- time_next_event[2] = sim_time + expon(mean_service);
- /* Move each customer in queue (if any) up one place. */
- for (i = 1; i <= num_in_q; ++i)
- time_arrival[i] = time_arrival[i + 1];
- }
- }
- void report(void) /* Report generator function. */
- {
- /* Compute and write estimates of desired measures of performance. */
- fprintf(outfile, "nnAverage delay in queue%11.3f minutesnn",
- total_of_delays / num_custs_delayed);
- fprintf(outfile, "Average number in queue%10.3fnn",
- area_num_in_q / sim_time);
- fprintf(outfile, "Server utilization%15.3fnn",
- area_server_status / sim_time);
- fprintf(outfile, "Time simulation ended%12.3f minutes", sim_time);
- }
- void update_time_avg_stats(void) /* Update area accumulators for time-average
- statistics. */
- {
- float time_since_last_event;
- /* Compute time since last event, and update last-event-time marker. */
- time_since_last_event = sim_time - time_last_event;
- time_last_event = sim_time;
- /* Update area under number-in-queue function. */
- area_num_in_q += num_in_q * time_since_last_event;
- /* Update area under server-busy indicator function. */
- area_server_status += server_status * time_since_last_event;
- }
- float expon(float mean) /* Exponential variate generation function. */
- {
- /* Return an exponential random variate with mean "mean". */
- return -mean * log(lcgrand(1));
- }
- /* Prime modulus multiplicative linear congruential generator
- Z[i] = (630360016 * Z[i-1]) (mod(pow(2,31) - 1)), based on Marse and Roberts'
- portable FORTRAN random-number generator UNIRAN. Multiple (100) streams are
- supported, with seeds spaced 100,000 apart. Throughout, input argument
- "stream" must be an int giving the desired stream number. The header file
- lcgrand.h must be included in the calling program (#include "lcgrand.h")
- before using these functions.
- Usage: (Three functions)
- 1. To obtain the next U(0,1) random number from stream "stream," execute
- u = lcgrand(stream);
- where lcgrand is a float function. The float variable u will contain the
- next random number.
- 2. To set the seed for stream "stream" to a desired value zset, execute
- lcgrandst(zset, stream);
- where lcgrandst is a void function and zset must be a long set to the
- desired seed, a number between 1 and 2147483646 (inclusive). Default
- seeds for all 100 streams are given in the code.
- 3. To get the current (most recently used) integer in the sequence being
- generated for stream "stream" into the long variable zget, execute
- zget = lcgrandgt(stream);
- where lcgrandgt is a long function. */
- /* Define the constants. */
- #define MODLUS 2147483647
- #define MULT1 24112
- #define MULT2 26143
- /* Set the default seeds for all 100 streams. */
- static long zrng[] =
- { 1,
- 1973272912, 281629770, 20006270,1280689831,2096730329,1933576050,
- 913566091, 246780520,1363774876, 604901985,1511192140,1259851944,
- 824064364, 150493284, 242708531, 75253171,1964472944,1202299975,
- 233217322,1911216000, 726370533, 403498145, 993232223,1103205531,
- 762430696,1922803170,1385516923, 76271663, 413682397, 726466604,
- 336157058,1432650381,1120463904, 595778810, 877722890,1046574445,
- 68911991,2088367019, 748545416, 622401386,2122378830, 640690903,
- 1774806513,2132545692,2079249579, 78130110, 852776735,1187867272,
- 1351423507,1645973084,1997049139, 922510944,2045512870, 898585771,
- 243649545,1004818771, 773686062, 403188473, 372279877,1901633463,
- 498067494,2087759558, 493157915, 597104727,1530940798,1814496276,
- 536444882,1663153658, 855503735, 67784357,1432404475, 619691088,
- 119025595, 880802310, 176192644,1116780070, 277854671,1366580350,
- 1142483975,2026948561,1053920743, 786262391,1792203830,1494667770,
- 1923011392,1433700034,1244184613,1147297105, 539712780,1545929719,
- 190641742,1645390429, 264907697, 620389253,1502074852, 927711160,
- 364849192,2049576050, 638580085, 547070247 };
- /* Generate the next random number. */
- float lcgrand(int stream)
- {
- long zi, lowprd, hi31;
- zi = zrng[stream];
- lowprd = (zi & 65535) * MULT1;
- hi31 = (zi >> 16) * MULT1 + (lowprd >> 16);
- zi = ((lowprd & 65535) - MODLUS) +
- ((hi31 & 32767) << 16) + (hi31 >> 15);
- if (zi < 0) zi += MODLUS;
- lowprd = (zi & 65535) * MULT2;
- hi31 = (zi >> 16) * MULT2 + (lowprd >> 16);
- zi = ((lowprd & 65535) - MODLUS) +
- ((hi31 & 32767) << 16) + (hi31 >> 15);
- if (zi < 0) zi += MODLUS;
- zrng[stream] = zi;
- return (zi >> 7 | 1) / 16777216.0;
- }
- void lcgrandst (long zset, int stream) /* Set the current zrng for stream
- "stream" to zset. */
- {
- zrng[stream] = zset;
- }
- long lcgrandgt (int stream) /* Return the current zrng for stream "stream". */
- {
- return zrng[stream];
- }