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

行业应用

开发平台:

Visual C++

  1. /* External definitions for inventory system. */
  2. #include <stdio.h>
  3. #include <math.h>
  4. #include "lcgrand.h"  /* Header file for random-number generator. */
  5. int   amount, bigs, initial_inv_level, inv_level, next_event_type, num_events,
  6.       num_months, num_values_demand, smalls;
  7. float area_holding, area_shortage, holding_cost, incremental_cost, maxlag,
  8.       mean_interdemand, minlag, prob_distrib_demand[26], setup_cost,
  9.       shortage_cost, sim_time, time_last_event, time_next_event[5],
  10.       total_ordering_cost;
  11. FILE  *infile, *outfile;
  12. void  initialize(void);
  13. void  timing(void);
  14. void  order_arrival(void);
  15. void  demand(void);
  16. void  evaluate(void);
  17. void  report(void);
  18. void  update_time_avg_stats(void);
  19. float expon(float mean);
  20. int   random_integer(float prob_distrib []);
  21. float uniform(float a, float b);
  22. main()  /* Main function. */
  23. {
  24.     int i, num_policies;
  25.     /* Open input and output files. */
  26.     infile  = fopen("inv.in",  "r");
  27.     outfile = fopen("inv.out", "w");
  28.     /* Specify the number of events for the timing function. */
  29.     num_events = 4;
  30.     /* Read input parameters. */
  31.     fscanf(infile, "%d %d %d %d %f %f %f %f %f %f %f",
  32.            &initial_inv_level, &num_months, &num_policies, &num_values_demand,
  33.            &mean_interdemand, &setup_cost, &incremental_cost, &holding_cost,
  34.            &shortage_cost, &minlag, &maxlag);
  35.     for (i = 1; i <= num_values_demand; ++i)
  36.         fscanf(infile, "%f", &prob_distrib_demand[i]);
  37.     /* Write report heading and input parameters. */
  38.     fprintf(outfile, "Single-product inventory systemnn");
  39.     fprintf(outfile, "Initial inventory level%24d itemsnn",
  40.             initial_inv_level);
  41.     fprintf(outfile, "Number of demand sizes%25dnn", num_values_demand);
  42.     fprintf(outfile, "Distribution function of demand sizes  ");
  43.     for (i = 1; i <= num_values_demand; ++i)
  44.         fprintf(outfile, "%8.3f", prob_distrib_demand[i]);
  45.     fprintf(outfile, "nnMean interdemand time%26.2fnn", mean_interdemand);
  46.     fprintf(outfile, "Delivery lag range%29.2f to%10.2f monthsnn", minlag,
  47.             maxlag);
  48.     fprintf(outfile, "Length of the simulation%23d monthsnn", num_months);
  49.     fprintf(outfile, "K =%6.1f   i =%6.1f   h =%6.1f   pi =%6.1fnn",
  50.             setup_cost, incremental_cost, holding_cost, shortage_cost);
  51.     fprintf(outfile, "Number of policies%29dnn", num_policies);
  52.     fprintf(outfile, "                 Average        Average");
  53.     fprintf(outfile, "        Average        Averagen");
  54.     fprintf(outfile, "  Policy       total cost    ordering cost");
  55.     fprintf(outfile, "  holding cost   shortage cost");
  56.     /* Run the simulation varying the inventory policy. */
  57.     for (i = 1; i <= num_policies; ++i) {
  58.         /* Read the inventory policy, and initialize the simulation. */
  59.         fscanf(infile, "%d %d", &smalls, &bigs);
  60.         initialize();
  61.         /* Run the simulation until it terminates after an end-simulation event
  62.            (type 3) occurs. */
  63.         do {
  64.             /* Determine the next event. */
  65.             timing();
  66.             /* Update time-average statistical accumulators. */
  67.             update_time_avg_stats();
  68.             /* Invoke the appropriate event function. */
  69.             switch (next_event_type) {
  70.                 case 1:
  71.                     order_arrival();
  72.                     break;
  73.                 case 2:
  74.                     demand();
  75.                     break;
  76.                 case 4:
  77.                     evaluate();
  78.                     break;
  79.                 case 3:
  80.                     report();
  81.                     break;
  82.             }
  83.         /* If the event just executed was not the end-simulation event (type 3),
  84.            continue simulating.  Otherwise, end the simulation for the current
  85.            (s,S) pair and go on to the next pair (if any). */
  86.         } while (next_event_type != 3);
  87.     }
  88.     /* End the simulations. */
  89.     fclose(infile);
  90.     fclose(outfile);
  91.     return 0;
  92. }
  93. void initialize(void)  /* Initialization function. */
  94. {
  95.     /* Initialize the simulation clock. */
  96.     sim_time = 0.0;
  97.     /* Initialize the state variables. */
  98.     inv_level       = initial_inv_level;
  99.     time_last_event = 0.0;
  100.     /* Initialize the statistical counters. */
  101.     total_ordering_cost = 0.0;
  102.     area_holding        = 0.0;
  103.     area_shortage       = 0.0;
  104.     /* Initialize the event list.  Since no order is outstanding, the order-
  105.        arrival event is eliminated from consideration. */
  106.     time_next_event[1] = 1.0e+30;
  107.     time_next_event[2] = sim_time + expon(mean_interdemand);
  108.     time_next_event[3] = num_months;
  109.     time_next_event[4] = 0.0;
  110. }
  111. void timing(void)  /* Timing function. */
  112. {
  113.     int   i;
  114.     float min_time_next_event = 1.0e+29;
  115.     next_event_type = 0;
  116.     /* Determine the event type of the next event to occur. */
  117.     for (i = 1; i <= num_events; ++i)
  118.         if (time_next_event[i] < min_time_next_event) {
  119.             min_time_next_event = time_next_event[i];
  120.             next_event_type     = i;
  121.         }
  122.     /* Check to see whether the event list is empty. */
  123.     if (next_event_type == 0) {
  124.         /* The event list is empty, so stop the simulation */
  125.         fprintf(outfile, "nEvent list empty at time %f", sim_time);
  126.         exit(1);
  127.     }
  128.     /* The event list is not empty, so advance the simulation clock. */
  129.     sim_time = min_time_next_event;
  130. }
  131. void order_arrival(void)  /* Order arrival event function. */
  132. {
  133.     /* Increment the inventory level by the amount ordered. */
  134.     inv_level += amount;
  135.     /* Since no order is now outstanding, eliminate the order-arrival event from
  136.        consideration. */
  137.     time_next_event[1] = 1.0e+30;
  138. }
  139. void demand(void)  /* Demand event function. */
  140. {
  141.     /* Decrement the inventory level by a generated demand size. */
  142.     inv_level -= random_integer(prob_distrib_demand);
  143.     /* Schedule the time of the next demand. */
  144.     time_next_event[2] = sim_time + expon(mean_interdemand);
  145. }
  146. void evaluate(void)  /* Inventory-evaluation event function. */
  147. {
  148.     /* Check whether the inventory level is less than smalls. */
  149.     if (inv_level < smalls) {
  150.         /* The inventory level is less than smalls, so place an order for the
  151.            appropriate amount. */
  152.         amount               = bigs - inv_level;
  153.         total_ordering_cost += setup_cost + incremental_cost * amount;
  154.         /* Schedule the arrival of the order. */
  155.         time_next_event[1] = sim_time + uniform(minlag, maxlag);
  156.     }
  157.     /* Regardless of the place-order decision, schedule the next inventory
  158.        evaluation. */
  159.     time_next_event[4] = sim_time + 1.0;
  160. }
  161. void report(void)  /* Report generator function. */
  162. {
  163.     /* Compute and write estimates of desired measures of performance. */
  164.     float avg_holding_cost, avg_ordering_cost, avg_shortage_cost;
  165.     avg_ordering_cost = total_ordering_cost / num_months;
  166.     avg_holding_cost  = holding_cost * area_holding / num_months;
  167.     avg_shortage_cost = shortage_cost * area_shortage / num_months;
  168.     fprintf(outfile, "nn(%3d,%3d)%15.2f%15.2f%15.2f%15.2f",
  169.             smalls, bigs,
  170.             avg_ordering_cost + avg_holding_cost + avg_shortage_cost,
  171.             avg_ordering_cost, avg_holding_cost, avg_shortage_cost);
  172. }
  173. void update_time_avg_stats(void)  /* Update area accumulators for time-average
  174.                                      statistics. */
  175. {
  176.     float time_since_last_event;
  177.     /* Compute time since last event, and update last-event-time marker. */
  178.     time_since_last_event = sim_time - time_last_event;
  179.     time_last_event       = sim_time;
  180.     /* Determine the status of the inventory level during the previous interval.
  181.        If the inventory level during the previous interval was negative, update
  182.        area_shortage.  If it was positive, update area_holding.  If it was zero,
  183.        no update is needed. */
  184.     if (inv_level < 0)
  185.         area_shortage -= inv_level * time_since_last_event;
  186.     else if (inv_level > 0)
  187.         area_holding  += inv_level * time_since_last_event;
  188. }
  189. float expon(float mean)  /* Exponential variate generation function. */
  190. {
  191.     /* Return an exponential random variate with mean "mean". */
  192.     return -mean * log(lcgrand(1));
  193. }
  194. int random_integer(float prob_distrib[])  /* Random integer generation
  195.                                              function. */
  196. {
  197.     int   i;
  198.     float u;
  199.     /* Generate a U(0,1) random variate. */
  200.     u = lcgrand(1);
  201.     /* Return a random integer in accordance with the (cumulative) distribution
  202.        function prob_distrib. */
  203.     for (i = 1; u >= prob_distrib[i]; ++i)
  204.         ;
  205.     return i;
  206. }
  207. float uniform(float a, float b)  /* Uniform variate generation function. */
  208. {
  209.     /* Return a U(a,b) random variate. */
  210.     return a + lcgrand(1) * (b - a);
  211. }