# for the inventory simulation of sec 1 5 suppose that the inventory is perishable hav 5192188

**For the inventory simulation of Sec. 1.5, suppose that the inventory is perishable, having a shelf life distributed uniformly between 1.5 and 2.5 months. That is, if an item has a shelf life of l months, then l months after it is placed in inventory it spoils and is of no value to the company. (Note that different items in an order from the supplier will have different shelf lives.) The company discovers that an itemis spoiled only upon examination before a sale. If an item is determined to be spoiled, it is discarded and the next itemin the inventory is examined. Assume that items in the inventory are processed in a FIFO manner. Repeat the nine simulation runs and assume the same costs as before. Also compute the proportion of items taken out of the inventory that are discarded due to being spoiled.**

inv.c

/* External definitions for inventory system. */

#include

#include

#include “lcgrand.h” /* Header file for random-number generator. */

int amount, bigs, initial_inv_level, inv_level, next_event_type, num_events,

num_months, num_values_demand, smalls;

float area_holding, area_shortage, holding_cost, incremental_cost, maxlag,

mean_interdemand, minlag, prob_distrib_demand[26], setup_cost,

shortage_cost, sim_time, time_last_event, time_next_event[5],

total_ordering_cost;

FILE *infile, *outfile;

void initialize(void);

void timing(void);

void order_arrival(void);

void demand(void);

void evaluate(void);

void report(void);

void update_time_avg_stats(void);

float expon(float mean);

int random_integer(float prob_distrib []);

float uniform(float a, float b);

main() /* Main function. */

{

int i, num_policies;

/* Open input and output files. */

infile = fopen(“inv.in”, “r”);

outfile = fopen(“inv.out”, “w”);

/* Specify the number of events for the timing function. */

num_events = 4;

/* Read input parameters. */

fscanf(infile, “%d %d %d %d %f %f %f %f %f %f %f”,

&initial_inv_level, &num_months, &num_policies, &num_values_demand,

&mean_interdemand, &setup_cost, &incremental_cost, &holding_cost,

&shortage_cost, &minlag, &maxlag);

for (i = 1; i

fscanf(infile, “%f”, &prob_distrib_demand[i]);

/* Write report heading and input parameters. */

fprintf(outfile, “Single-product inventory systemnn”);

fprintf(outfile, “Initial inventory level%24d itemsnn”,

initial_inv_level);

fprintf(outfile, “Number of demand sizes%25dnn”, num_values_demand);

fprintf(outfile, “Distribution function of demand sizes “);

for (i = 1; i

fprintf(outfile, “%8.3f”, prob_distrib_demand[i]);

fprintf(outfile, “nnMean interdemand time%26.2fnn”, mean_interdemand);

fprintf(outfile, “Delivery lag range%29.2f to%10.2f monthsnn”, minlag,

maxlag);

fprintf(outfile, “Length of the simulation%23d monthsnn”, num_months);

fprintf(outfile, “K =%6.1f i =%6.1f h =%6.1f pi =%6.1fnn”,

setup_cost, incremental_cost, holding_cost, shortage_cost);

fprintf(outfile, “Number of policies%29dnn”, num_policies);

fprintf(outfile, ” Average Average”);

fprintf(outfile, ” Average Averagen”);

fprintf(outfile, ” Policy total cost ordering cost”);

fprintf(outfile, ” holding cost shortage cost”);

/* Run the simulation varying the inventory policy. */

for (i = 1; i

/* Read the inventory policy, and initialize the simulation. */

fscanf(infile, “%d %d”, &smalls, &bigs);

initialize();

/* Run the simulation until it terminates after an end-simulation event

(type 3) occurs. */

do {

/* 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:

order_arrival();

break;

case 2:

demand();

break;

case 4:

evaluate();

break;

case 3:

report();

break;

}

/* If the event just executed was not the end-simulation event (type 3),

continue simulating. Otherwise, end the simulation for the current

(s,S) pair and go on to the next pair (if any). */

} while (next_event_type != 3);

}

/* End the simulations. */

fclose(infile);

fclose(outfile);

return 0;

}

void initialize(void) /* Initialization function. */

{

/* Initialize the simulation clock. */

sim_time = 0.0;

/* Initialize the state variables. */

inv_level = initial_inv_level;

time_last_event = 0.0;

/* Initialize the statistical counters. */

total_ordering_cost = 0.0;

area_holding = 0.0;

area_shortage = 0.0;

/* Initialize the event list. Since no order is outstanding, the order-

arrival event is eliminated from consideration. */

time_next_event[1] = 1.0e+30;

time_next_event[2] = sim_time + expon(mean_interdemand);

time_next_event[3] = num_months;

time_next_event[4] = 0.0;

}

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

if (time_next_event[i]

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 order_arrival(void) /* Order arrival event function. */

{

/* Increment the inventory level by the amount ordered. */

inv_level += amount;

/* Since no order is now outstanding, eliminate the order-arrival event from

consideration. */

time_next_event[1] = 1.0e+30;

}

void demand(void) /* Demand event function. */

{

/* Decrement the inventory level by a generated demand size. */

inv_level -= random_integer(prob_distrib_demand);

/* Schedule the time of the next demand. */

time_next_event[2] = sim_time + expon(mean_interdemand);

}

void evaluate(void) /* Inventory-evaluation event function. */

{

/* Check whether the inventory level is less than smalls. */

if (inv_level

/* The inventory level is less than smalls, so place an order for the

appropriate amount. */

amount = bigs – inv_level;

total_ordering_cost += setup_cost + incremental_cost * amount;

/* Schedule the arrival of the order. */

time_next_event[1] = sim_time + uniform(minlag, maxlag);

}

/* Regardless of the place-order decision, schedule the next inventory

evaluation. */

time_next_event[4] = sim_time + 1.0;

}

void report(void) /* Report generator function. */

{

/* Compute and write estimates of desired measures of performance. */

float avg_holding_cost, avg_ordering_cost, avg_shortage_cost;

avg_ordering_cost = total_ordering_cost / num_months;

avg_holding_cost = holding_cost * area_holding / num_months;

avg_shortage_cost = shortage_cost * area_shortage / num_months;

fprintf(outfile, “nn(%3d,%3d)%15.2f%15.2f%15.2f%15.2f”,

smalls, bigs,

avg_ordering_cost + avg_holding_cost + avg_shortage_cost,

avg_ordering_cost, avg_holding_cost, avg_shortage_cost);

}

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;

/* Determine the status of the inventory level during the previous interval.

If the inventory level during the previous interval was negative, update

area_shortage. If it was positive, update area_holding. If it was zero,

no update is needed. */

if (inv_level

area_shortage -= inv_level * time_since_last_event;

else if (inv_level > 0)

area_holding += inv_level * 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));

}

int random_integer(float prob_distrib[]) /* Random integer generation

function. */

{

int i;

float u;

/* Generate a U(0,1) random variate. */

u = lcgrand(1);

/* Return a random integer in accordance with the (cumulative) distribution

function prob_distrib. */

for (i = 1; u >= prob_distrib[i]; ++i)

;

return i;

}

float uniform(float a, float b) /* Uniform variate generation function. */

{

/* Return a U(a,b) random variate. */

return a + lcgrand(1) * (b – a);

lcgrand.c

/* 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

lowprd = (zi & 65535) * MULT2;

hi31 = (zi >> 16) * MULT2 + (lowprd >> 16);

zi = ((lowprd & 65535) – MODLUS) +

((hi31 & 32767) << 16) + (hi31 >> 15);

if (zi

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];

}