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

行业应用

开发平台:

Visual C++

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