MM1ALT.C
上传用户:aozhi88
上传日期:2022-07-10
资源大小:255k
文件大小:12k
源码类别:

行业应用

开发平台:

Visual C++

  1. /* External definitions for single-server queueing system, fixed run length. */
  2. #include <stdio.h>
  3. #include <math.h>
  4. /*#include "lcgrand.h"   Header file for random-number generator. */
  5. #define Q_LIMIT 100  /* Limit on queue length. */
  6. #define BUSY      1  /* Mnemonics for server's being busy */
  7. #define IDLE      0  /* and idle. */
  8. int   next_event_type, num_custs_delayed, num_events, num_in_q, server_status;
  9. float area_num_in_q, area_server_status, mean_interarrival, mean_service,
  10.       sim_time, time_arrival[Q_LIMIT + 1], time_end, time_last_event,
  11.       time_next_event[4], total_of_delays;
  12. FILE  *infile, *outfile;
  13. /* The following 3 declarations are for use of the random-number generator
  14.    lcgrand and the associated functions lcgrandst and lcgrandgt for seed
  15.    management.  This file (named lcgrand.h) should be included in any program
  16.    using these functions by executing
  17.        #include "lcgrand.h"
  18.    before referencing the functions. */
  19. float lcgrand(int stream);
  20. void  lcgrandst(long zset, int stream);
  21. long  lcgrandgt(int stream);
  22. void  initialize(void);
  23. void  timing(void);
  24. void  arrive(void);
  25. void  depart(void);
  26. void  report(void);
  27. void  update_time_avg_stats(void);
  28. float expon(float mean);
  29. main()  /* Main function. */
  30. {
  31.     /* Open input and output files. */
  32.     infile  = fopen("mm1alt.in",  "r");
  33.     outfile = fopen("mm1alt.out", "w");
  34.     /* Specify the number of events for the timing function. */
  35.     num_events = 3;
  36.     /* Read input parameters. */
  37.     fscanf(infile, "%f %f %f", &mean_interarrival, &mean_service, &time_end);
  38.     /* Write report heading and input parameters. */
  39.     fprintf(outfile, "Single-server queueing system with fixed run");
  40.     fprintf(outfile, " lengthnn");
  41.     fprintf(outfile, "Mean interarrival time%11.3f minutesnn",
  42.             mean_interarrival);
  43.     fprintf(outfile, "Mean service time%16.3f minutesnn", mean_service);
  44.     fprintf(outfile, "Length of the simulation%9.3f minutesnn", time_end);
  45.     /* Initialize the simulation. */
  46.     initialize();
  47.     /* Run the simulation until it terminates after an end-simulation event
  48.        (type 3) occurs. */
  49.     do {
  50.         /* Determine the next event. */
  51.         timing();
  52.         /* Update time-average statistical accumulators. */
  53.         update_time_avg_stats();
  54.         /* Invoke the appropriate event function. */
  55.         switch (next_event_type) {
  56.             case 1:
  57.                 arrive();
  58.                 break;
  59.             case 2:
  60.                 depart();
  61.                 break;
  62.             case 3:
  63.                 report();
  64.                 break;
  65.         }
  66.     /* If the event just executed was not the end-simulation event (type 3),
  67.        continue simulating.  Otherwise, end the simulation. */
  68.     } while (next_event_type != 3);
  69.     fclose(infile);
  70.     fclose(outfile);
  71.     return 0;
  72. }
  73. void initialize(void)  /* Initialization function. */
  74. {
  75.     /* Initialize the simulation clock. */
  76.     sim_time = 0.0;
  77.     /* Initialize the state variables. */
  78.     server_status   = IDLE;
  79.     num_in_q        = 0;
  80.     time_last_event = 0.0;
  81.     /* Initialize the statistical counters. */
  82.     num_custs_delayed  = 0;
  83.     total_of_delays    = 0.0;
  84.     area_num_in_q      = 0.0;
  85.     area_server_status = 0.0;
  86.     /* Initialize event list.  Since no customers are present, the departure
  87.        (service completion) event is eliminated from consideration.  The end-
  88.        simulation event (type 3) is scheduled for time time_end. */
  89.     time_next_event[1] = sim_time + expon(mean_interarrival);
  90.     time_next_event[2] = 1.0e+30;
  91.     time_next_event[3] = time_end;
  92. }
  93. void timing(void)  /* Timing function. */
  94. {
  95.     int   i;
  96.     float min_time_next_event = 1.0e+29;
  97.     next_event_type = 0;
  98.     /* Determine the event type of the next event to occur. */
  99.     for (i = 1; i <= num_events; ++i)
  100.         if (time_next_event[i] < min_time_next_event) {
  101.             min_time_next_event = time_next_event[i];
  102.             next_event_type     = i;
  103.         }
  104.     /* Check to see whether the event list is empty. */
  105.     if (next_event_type == 0) {
  106.         /* The event list is empty, so stop the simulation */
  107.         fprintf(outfile, "nEvent list empty at time %f", sim_time);
  108.         exit(1);
  109.     }
  110.     /* The event list is not empty, so advance the simulation clock. */
  111.     sim_time = min_time_next_event;
  112. }
  113. void arrive(void)  /* Arrival event function. */
  114. {
  115.     float delay;
  116.     /* Schedule next arrival. */
  117.     time_next_event[1] = sim_time + expon(mean_interarrival);
  118.     /* Check to see whether server is busy. */
  119.     if (server_status == BUSY) {
  120.         /* Server is busy, so increment number of customers in queue. */
  121.         ++num_in_q;
  122.         /* Check to see whether an overflow condition exists. */
  123.         if (num_in_q > Q_LIMIT) {
  124.             /* The queue has overflowed, so stop the simulation. */
  125.             fprintf(outfile, "nOverflow of the array time_arrival at");
  126.             fprintf(outfile, " time %f", sim_time);
  127.             exit(2);
  128.         }
  129.         /* There is still room in the queue, so store the time of arrival of the
  130.            arriving customer at the (new) end of time_arrival. */
  131.         time_arrival[num_in_q] = sim_time;
  132.     }
  133.     else {
  134.         /* Server is idle, so arriving customer has a delay of zero.  (The
  135.            following two statements are for program clarity and do not affect
  136.            the results of the simulation.) */
  137.         delay            = 0.0;
  138.         total_of_delays += delay;
  139.         /* Increment the number of customers delayed, and make server busy. */
  140.         ++num_custs_delayed;
  141.         server_status = BUSY;
  142.         /* Schedule a departure (service completion). */
  143.         time_next_event[2] = sim_time + expon(mean_service);
  144.     }
  145. }
  146. void depart(void)  /* Departure event function. */
  147. {
  148.     int   i;
  149.     float delay;
  150.     /* Check to see whether the queue is empty. */
  151.     if (num_in_q == 0) {
  152.         /* The queue is empty so make the server idle and eliminate the
  153.            departure (service completion) event from consideration. */
  154.         server_status      = IDLE;
  155.         time_next_event[2] = 1.0e+30;
  156.     }
  157.     else {
  158.         /* The queue is nonempty, so decrement the number of customers in
  159.            queue. */
  160.         --num_in_q;
  161.         /* Compute the delay of the customer who is beginning service and update
  162.            the total delay accumulator. */
  163.         delay            = sim_time - time_arrival[1];
  164.         total_of_delays += delay;
  165.         /* Increment the number of customers delayed, and schedule departure. */
  166.         ++num_custs_delayed;
  167.         time_next_event[2] = sim_time + expon(mean_service);
  168.         /* Move each customer in queue (if any) up one place. */
  169.         for (i = 1; i <= num_in_q; ++i)
  170.             time_arrival[i] = time_arrival[i + 1];
  171.     }
  172. }
  173. void report(void)  /* Report generator function. */
  174. {
  175.     /* Compute and write estimates of desired measures of performance. */
  176.     fprintf(outfile, "nnAverage delay in queue%11.3f minutesnn",
  177.             total_of_delays / num_custs_delayed);
  178.     fprintf(outfile, "Average number in queue%10.3fnn",
  179.             area_num_in_q / sim_time);
  180.     fprintf(outfile, "Server utilization%15.3fnn",
  181.             area_server_status / sim_time);
  182.     fprintf(outfile, "Number of delays completed%7d",
  183.             num_custs_delayed);
  184. }
  185. void update_time_avg_stats(void)  /* Update area accumulators for time-average
  186.                                      statistics. */
  187. {
  188.     float time_since_last_event;
  189.     /* Compute time since last event, and update last-event-time marker. */
  190.     time_since_last_event = sim_time - time_last_event;
  191.     time_last_event       = sim_time;
  192.     /* Update area under number-in-queue function. */
  193.     area_num_in_q      += num_in_q * time_since_last_event;
  194.     /* Update area under server-busy indicator function. */
  195.     area_server_status += server_status * time_since_last_event;
  196. }
  197. float expon(float mean)  /* Exponential variate generation function. */
  198. {
  199.     /* Return an exponential random variate with mean "mean". */
  200.     return -mean * log(lcgrand(25));
  201. }
  202. /* Prime modulus multiplicative linear congruential generator
  203.    Z[i] = (630360016 * Z[i-1]) (mod(pow(2,31) - 1)), based on Marse and Roberts'
  204.    portable FORTRAN random-number generator UNIRAN.  Multiple (100) streams are
  205.    supported, with seeds spaced 100,000 apart.  Throughout, input argument
  206.    "stream" must be an int giving the desired stream number.  The header file
  207.    lcgrand.h must be included in the calling program (#include "lcgrand.h")
  208.    before using these functions.
  209.    Usage: (Three functions)
  210.    1. To obtain the next U(0,1) random number from stream "stream," execute
  211.           u = lcgrand(stream);
  212.       where lcgrand is a float function.  The float variable u will contain the
  213.       next random number.
  214.    2. To set the seed for stream "stream" to a desired value zset, execute
  215.           lcgrandst(zset, stream);
  216.       where lcgrandst is a void function and zset must be a long set to the
  217.       desired seed, a number between 1 and 2147483646 (inclusive).  Default
  218.       seeds for all 100 streams are given in the code.
  219.    3. To get the current (most recently used) integer in the sequence being
  220.       generated for stream "stream" into the long variable zget, execute
  221.           zget = lcgrandgt(stream);
  222.       where lcgrandgt is a long function. */
  223. /* Define the constants. */
  224. #define MODLUS 2147483647
  225. #define MULT1       24112
  226. #define MULT2       26143
  227. /* Set the default seeds for all 100 streams. */
  228. static long zrng[] =
  229. {         1,
  230.  1973272912, 281629770,  20006270,1280689831,2096730329,1933576050,
  231.   913566091, 246780520,1363774876, 604901985,1511192140,1259851944,
  232.   824064364, 150493284, 242708531,  75253171,1964472944,1202299975,
  233.   233217322,1911216000, 726370533, 403498145, 993232223,1103205531,
  234.   762430696,1922803170,1385516923,  76271663, 413682397, 726466604,
  235.   336157058,1432650381,1120463904, 595778810, 877722890,1046574445,
  236.    68911991,2088367019, 748545416, 622401386,2122378830, 640690903,
  237.  1774806513,2132545692,2079249579,  78130110, 852776735,1187867272,
  238.  1351423507,1645973084,1997049139, 922510944,2045512870, 898585771,
  239.   243649545,1004818771, 773686062, 403188473, 372279877,1901633463,
  240.   498067494,2087759558, 493157915, 597104727,1530940798,1814496276,
  241.   536444882,1663153658, 855503735,  67784357,1432404475, 619691088,
  242.   119025595, 880802310, 176192644,1116780070, 277854671,1366580350,
  243.  1142483975,2026948561,1053920743, 786262391,1792203830,1494667770,
  244.  1923011392,1433700034,1244184613,1147297105, 539712780,1545929719,
  245.   190641742,1645390429, 264907697, 620389253,1502074852, 927711160,
  246.   364849192,2049576050, 638580085, 547070247 };
  247. /* Generate the next random number. */
  248. float lcgrand(int stream)
  249. {
  250.     long zi, lowprd, hi31;
  251.     zi     = zrng[stream];
  252.     lowprd = (zi & 65535) * MULT1;
  253.     hi31   = (zi >> 16) * MULT1 + (lowprd >> 16);
  254.     zi     = ((lowprd & 65535) - MODLUS) +
  255.              ((hi31 & 32767) << 16) + (hi31 >> 15);
  256.     if (zi < 0) zi += MODLUS;
  257.     lowprd = (zi & 65535) * MULT2;
  258.     hi31   = (zi >> 16) * MULT2 + (lowprd >> 16);
  259.     zi     = ((lowprd & 65535) - MODLUS) +
  260.              ((hi31 & 32767) << 16) + (hi31 >> 15);
  261.     if (zi < 0) zi += MODLUS;
  262.     zrng[stream] = zi;
  263.     return (zi >> 7 | 1) / 16777216.0;
  264. }
  265. void lcgrandst (long zset, int stream) /* Set the current zrng for stream
  266.                                           "stream" to zset. */
  267. {
  268.     zrng[stream] = zset;
  269. }
  270. long lcgrandgt (int stream) /* Return the current zrng for stream "stream". */
  271. {
  272.     return zrng[stream];
  273. }