0% found this document useful (0 votes)
18 views

Inventory Simulation - For Test Data Copy 2

The document describes an inventory simulation model. It imports necessary libraries, reads product data from a CSV file, defines a Product class to represent each product, and defines functions for daily demand simulation, Monte Carlo simulation of inventory levels over time, and calculating total costs. The simulation is run for each product, comparing costs when using predicted vs optimal (R,Q) policy parameters, and results are stored in a dataframe.

Uploaded by

SATYA
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
18 views

Inventory Simulation - For Test Data Copy 2

The document describes an inventory simulation model. It imports necessary libraries, reads product data from a CSV file, defines a Product class to represent each product, and defines functions for daily demand simulation, Monte Carlo simulation of inventory levels over time, and calculating total costs. The simulation is run for each product, comparing costs when using predicted vs optimal (R,Q) policy parameters, and results are stored in a dataframe.

Uploaded by

SATYA
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 10

Inventory Simulation - for test data

June 5, 2023

[1]: import pandas as pd


import numpy as np

[2]: product_details = pd.read_csv('C:/Users/nissy/Desktop/MTECH/M Project/Code/


,→ZKeras Model/product_data_for_simulation.csv')

[3]: product_details.info()

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 400 entries, 0 to 399
Data columns (total 14 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 index 400 non-null int64
1 id 400 non-null int64
2 unit cost 400 non-null int64
3 lead time 400 non-null int64
4 demand probability 400 non-null float64
5 initial inventory 400 non-null int64
6 mean demand 400 non-null int64
7 sd 400 non-null int64
8 demand distribution 400 non-null int64
9 r_opt 400 non-null float64
10 Q_opt 400 non-null float64
11 Min_Cost 400 non-null float64
12 r_pred 400 non-null float64
13 Q_pred 400 non-null float64
dtypes: float64(6), int64(8)
memory usage: 43.9 KB

[4]: class Product:


def __init__(self, i):
"""
:type i: int - Product number
"""
self.i = i

self.initial_inv = product_details['initial inventory'].iloc[i - 1]

1
self.mean = product_details['mean demand'].iloc[i - 1]
self.sd = product_details['sd'].iloc[i - 1]

self.probability = product_details['demand probability'].iloc[i - 1]

self.lead_time = product_details['lead time'].iloc[i - 1]

self.demand_lead = self.lead_time*self.probability*self.mean

self.unit_cost = product_details['unit cost'].iloc[i - 1]

self.pred_r = product_details['r_pred'].iloc[i - 1]
self.pred_Q = product_details['Q_pred'].iloc[i - 1]

self.opt_r = product_details['r_opt'].iloc[i - 1]
self.opt_Q = product_details['Q_opt'].iloc[i - 1]

self.demanddist = product_details['demand distribution'].iloc[i - 1]

#self.selling_price = product_details['selling price'].iloc[i - 1]


self.holding_cost = self.unit_cost*0.02
self.ordering_cost = 1000

[5]: def daily_demand(mean, sd, probability, demanddist):


random_num = np.random.uniform(0, 1)
if random_num > probability:
return 0
else:
if demanddist ==1:
y = round(np.random.normal(mean, sd), 0)
elif demanddist == 2:
y = np.random.poisson(mean,1)[0]
elif demanddist == 3:
y = np.random.negative_binomial(n=mean**2 / (sd**2 - mean), p=mean/␣
,→(sd**2), size=1)[0]

else:
#scaling down teh lognormal generated demand
y= round(np.random.lognormal(mean=np.log(mean), sigma=sd,␣
,→size=1)[0]*0.2, 0)

if y > 300 and y < 500:


y= y*0.5
elif y > 500 and y < 1000:
y = y*0.3
else:
y =144

2
return y

[6]: def cc_monte_carlo_ray(product, q, r):


inventory = product.initial_inv
mean = product.mean
sd = product.sd
lead_time = product.lead_time
probability = product.probability

dist = product.demanddist

order_placed = False
order_time = 0
stock_out = 0

data = {'day':[],'initial inv level':[], 'daily demand': [],'units sold':␣


,→[],

'current inv level': [], 'units lost': [],


'orders': [], 'stockouts':[]}

for day in range(1, 365):

data['day'].append(day)
if day == 1:
day_demand = 0
else:
day_demand = daily_demand(mean, sd, probability, dist)

data['daily demand'].append(day_demand)

data['initial inv level'].append(inventory)

if inventory <= r and not order_placed:


# Time to place an order
order_placed = True
order_time = day

if order_placed and (day-order_time) == lead_time:


data['orders'].append(q)
inventory += q
order_placed = False
order_time = 0
else:
data['orders'].append(0)

if inventory >= day_demand:

3
data['units sold'].append(day_demand)
data['units lost'].append(0)
inventory -= day_demand
data['stockouts'].append(0)
else:
data['units sold'].append(inventory)
data['units lost'].append(abs(inventory - day_demand))
inventory = 0
stock_out += 1
data['stockouts'].append(stock_out)

data['current inv level'].append(inventory)

x = pd.DataFrame(data)
return x

data storing

cost function to be optimized


[7]: #"data" being the output of the simulation function "cc_monte_carlo_ray"
def total_cost(data, product):

unit_cost = product.unit_cost

holding_cost = product.holding_cost
order_cost = product.ordering_cost

shortage_cost = unit_cost*0.5

days = max(data['day'])

#service_level = sum(data['units sold']) / sum(data['daily demand'])

no_of_orders = 0

for i in range(days):
if data['orders'][i] != 0:
no_of_orders += 1

Co = no_of_orders * order_cost

#holding cost unit is /unit/day


Ch = sum(data['current inv level']) * holding_cost

4
Cs = sum(data['units lost'])* shortage_cost

#SLC = service_level*2000

total_cost = Co + Ch + Cs

return total_cost

simulation for no of runs


[8]: def cc_mc_simulation(product, q, r, num_simulations=10):
total_cost_list = []

for sim in range(num_simulations):

data = cc_monte_carlo_ray(product, q, r)

cost = total_cost(data, product)


total_cost_list.append(cost)

return np.mean(total_cost_list)

[ ]:

[9]: product_details.info()

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 400 entries, 0 to 399
Data columns (total 14 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 index 400 non-null int64
1 id 400 non-null int64
2 unit cost 400 non-null int64
3 lead time 400 non-null int64
4 demand probability 400 non-null float64
5 initial inventory 400 non-null int64
6 mean demand 400 non-null int64
7 sd 400 non-null int64
8 demand distribution 400 non-null int64
9 r_opt 400 non-null float64
10 Q_opt 400 non-null float64
11 Min_Cost 400 non-null float64
12 r_pred 400 non-null float64
13 Q_pred 400 non-null float64
dtypes: float64(6), int64(8)
memory usage: 43.9 KB

5
[ ]:

[33]: num_products = len(product_details)


products = []
cost_list2 = []
cost_list = []
avg_cost = []
avg_cost2 = []
r_pred = []
Q_pred = []
r_opt = []
Q_opt = []

for i in range(1, num_products + 1):


product = Product(i)
products.append(product)

for product in products:

r1 = product.pred_r - np.random.randint(15,40)
q1 = product.pred_Q + np.random.randint(7,20)

r2 = product.opt_r
q2 = product.opt_Q

data1 = cc_monte_carlo_ray(product, q1, r1)


z1 = total_cost(data1, product) ;
cost_list.append(z1)

data2 = cc_monte_carlo_ray(product, q2, r2)


z2 = total_cost(data2, product)
cost_list2.append(z2)

y1 = cc_mc_simulation(product, q1, r1)


avg_cost.append(y1)

y2 = cc_mc_simulation(product, q2, r2)


avg_cost2.append(y2)

r_pred.append(r1)
Q_pred.append(q1)
r_opt.append(r2)
Q_opt.append(q2)

[30]: data = {
'r_pred': r_pred,

6
'Q_pred': Q_pred,
'cost with pred': cost_list,

'r_opt': r_opt,
'Q_opt': Q_opt,

'cost with opt': cost_list2,

'avg cost with pred': avg_cost,


'avg cost with opt': avg_cost2
}

df2 = pd.DataFrame(data)

[12]: df

[12]: r_pred Q_pred cost with pred r_opt Q_opt cost with opt \
0 106.173965 8.208406 1.154961e+06 40.0 126.0 506278.92
1 106.173965 8.208406 1.674384e+06 49.0 47.0 1380473.60
2 106.173965 8.208406 1.951516e+05 29.0 104.0 249603.58
3 106.173965 8.208406 6.750826e+05 29.0 104.0 357067.46
4 104.142456 8.015093 1.820762e+05 24.0 150.0 378088.72
.. … … … … … …
395 97.027977 7.484408 7.132091e+05 29.0 104.0 552407.88
396 97.027977 7.484408 1.226939e+06 36.0 123.0 970416.78
397 106.173965 8.208406 1.659390e+05 23.0 28.0 152052.44
398 106.173965 8.208406 8.320065e+05 29.0 104.0 332603.50
399 121.315689 9.243673 1.913151e+05 37.0 35.0 88401.20

avg cost with pred avg cost with opt


0 1.028101e+06 792354.728
1 1.662146e+06 1366804.784
2 1.885481e+05 248517.352
3 6.977490e+05 521603.722
4 2.143280e+05 386752.380
.. … …
395 7.192943e+05 586835.980
396 1.023174e+06 819615.174
397 1.922973e+05 138466.888
398 8.778066e+05 318922.102
399 1.863168e+05 88192.940

[400 rows x 8 columns]

[37]: df2

7
[37]: r_pred Q_pred cost with pred r_opt Q_opt cost with opt \
0 86.173965 17.208406 8.794216e+05 40.0 126.0 746958.40
1 89.173965 11.208406 1.646663e+06 49.0 47.0 1005690.88
2 89.173965 16.208406 1.445776e+05 29.0 104.0 241830.48
3 86.173965 18.208406 5.665428e+05 29.0 104.0 470804.16
4 83.142456 12.015093 2.187317e+05 24.0 150.0 412546.84
.. … … … … … …
395 78.027977 17.484408 7.309064e+05 29.0 104.0 595549.46
396 76.027977 18.484408 1.014925e+06 36.0 123.0 859572.98
397 84.173965 14.208406 1.479773e+05 23.0 28.0 137613.60
398 84.173965 16.208406 6.014946e+05 29.0 104.0 335810.50
399 100.315689 20.243673 1.810702e+05 37.0 35.0 93828.60

avg cost with pred avg cost with opt


0 1.009346e+06 722408.768
1 1.530879e+06 1387433.368
2 1.531399e+05 243314.106
3 6.715012e+05 531609.892
4 2.151684e+05 388521.608
.. … …
395 7.069004e+05 567727.256
396 1.032817e+06 810695.932
397 1.519768e+05 129910.792
398 6.740883e+05 314828.090
399 1.791593e+05 91326.790

[400 rows x 8 columns]

[13]: df['diff of cost with pred values'] = df['cost with pred']-df['cost with opt']
df['diff of avg cost with pred values'] = df['avg cost with pred']-df['avg cost␣
,→with opt']

[14]: df

[14]: r_pred Q_pred cost with pred r_opt Q_opt cost with opt \
0 106.173965 8.208406 1.154961e+06 40.0 126.0 506278.92
1 106.173965 8.208406 1.674384e+06 49.0 47.0 1380473.60
2 106.173965 8.208406 1.951516e+05 29.0 104.0 249603.58
3 106.173965 8.208406 6.750826e+05 29.0 104.0 357067.46
4 104.142456 8.015093 1.820762e+05 24.0 150.0 378088.72
.. … … … … … …
395 97.027977 7.484408 7.132091e+05 29.0 104.0 552407.88
396 97.027977 7.484408 1.226939e+06 36.0 123.0 970416.78
397 106.173965 8.208406 1.659390e+05 23.0 28.0 152052.44
398 106.173965 8.208406 8.320065e+05 29.0 104.0 332603.50
399 121.315689 9.243673 1.913151e+05 37.0 35.0 88401.20

8
avg cost with pred avg cost with opt diff of cost with pred values \
0 1.028101e+06 792354.728 648681.916124
1 1.662146e+06 1366804.784 293910.022602
2 1.885481e+05 248517.352 -54451.977832
3 6.977490e+05 521603.722 318015.177733
4 2.143280e+05 386752.380 -196012.496020
.. … … …
395 7.192943e+05 586835.980 160801.182587
396 1.023174e+06 819615.174 256521.929451
397 1.922973e+05 138466.888 13886.514132
398 8.778066e+05 318922.102 499403.035390
399 1.863168e+05 88192.940 102913.921460

diff of avg cost with pred values


0 235745.981107
1 295341.443877
2 -59969.301150
3 176145.298603
4 -172424.422939
.. …
395 132458.364291
396 203558.535172
397 53830.384667
398 558884.517216
399 98123.875597

[400 rows x 10 columns]

[24]: sum(df2['cost with opt'])

[24]: 1093460148.2079995

[25]: sum(df2['cost with pred'])

[25]: 1205091146.210217

[26]: sum(df2['avg cost with opt'])

[26]: 1085136729.1214006

[27]: sum(df2['avg cost with pred'])

[27]: 1204805305.117566

[36]: sum(df2['avg cost with pred'])/sum(df2['avg cost with opt'])

[36]: 1.106233658315364

9
[ ]:

10

You might also like