0
$\begingroup$

I have to minimize the inventory remaining at end of the period(28 days). Each item would perish after a fixed number of days and we can order items only on certain weekdays(M,T,S,S). Demand is allowed not to be met if not possible. but no stockout situation. The inventory continuity constraint is giving infeasibility to me because of situations when all inventory has perished on a day, we can't order on the same day also so ending inventory equals demand and is conflicting with other equations, how to model the situation when demand may or may not be met? Below is the code. Days are from 241-269. Day 240 is the day of initial on-hand availability. Inv can be continuous but order qty is integer.

Here is formulation:

item=[1...10], days=[241...269]
dvar's --> x(i,d) {Binary} y(i,d) {Integer purchase qty.} I(i,d) {Continuous, >0 inventory at EOD}

Min: lpSum over i,d (I(i,d) if d==269)

s.t. C_1 : x(i,d)=0 if d in {Mon,Thu,Sat,Sun}
     C_2 : I(i,d)= On-hand inv at beginning of period(data given) if d=240
     C_3 : for all days 80 <= lpSum over i (y(i,d)) <=150
     C_4 : I(i,d+s)] <= (1-x(i,d))*M
(Inventory to be salvaged if shelf life days are passed, s is shelf days for each item)
     C_5 :  y(i,d)<= M*x(i,d)
     C_6 : for all i,d 
             if demand_forcast(i,d) >= I(i,d-1):
                  I(i,d) == y(i,d)
             else:
                  I(i,d) = I(i,d-1) + y(i,d) -demand_forcast(i,d)

And here is python code:

item = demand['item_code'].unique()
days = range(240,270,1)

item_days = [(i,d) for i in item for d in days]

dmd_forecast = demand.set_index(['item_code','doy']).forecast_quantity.to_dict()
onhand_qty = onhand.set_index(['item_code','doy']).onhand_quantity.to_dict()
no_order = no_purchase_days.set_index(['item_code','doy']).delivery.to_dict()  ## list of item-days for no order
shelf_days = shelf_life.set_index(['item_code']).item_shelf_life.to_dict()

#------------------------------------------
prob = LpProblem("Min_wastage",LpMinimize)

x = LpVariable.dicts("Order-y-n",item_days, cat="Binary")  ## x at 240 also to be set zero

y = LpVariable.dicts("Order-Qty",item_days,lowBound = 0, cat="Integer")

I = LpVariable.dicts("EOD_Inv",item_days, lowBound = 0, cat="Continuous") 

# objective function

## Minimize the inventory left at end of period of 29 days

prob += (
    lpSum(I[(i,d)] for i in item for d in days if d == 269 )
)

## Constraint 1: No Delivery on Mon, Thu, Sat, Sun

for i in no_order:
    prob += (
           y[i] == 0
    )
    
## Also At time period 240 no order

for i in item:
    for d in days:
        if d==240:
            prob += (
                y[(i,d)] == 0
            )
## Constraint 2: Fix on hand inventory values at start of period, start of day
            
for i in onhand_qty:
    prob += (
        I[i] == onhand_qty[i]
    )

## Constraint 3 : Inv-continuity Equation

            
for i in item:
    for d in days:
        if d>=241:
            if dmd_forecast[(i,d)] >= I[(i,d-1)]:
                prob += (
                    I[(i,d)] == dmd_forecast[(i,d)]- I[(i,d-1)] + y[(i,d)]
                )
            else:
                prob += (
                    I[(i,d)] == I[(i,d-1)] + y[(i,d)] - dmd_forecast[(i,d)]
                )
## Constraint 5: Inventory to be salvaged if shelf life days are passed.

## 250 as max. shelf days over all items is 19 days. Also this constraint needs to be written in better way for each item.

for i in item:
    for d in days:
        if d <= 260:
            prob += (
                    I[(i,d+shelf_days[i])] <= (1-x[(i,d)])*1000
            )

## Constraint 6: if x is 1, the order can placed y > 0, 170 is the value of Big-M, when y is zero... x is forced zero.

for i in item:
    for d in days:
        prob += (
            x[(i,d)] <= y[(i,d)]
        )

$\endgroup$

2 Answers 2

1
$\begingroup$

Shouldn't the right side of the first part of your constraint 3 (if today's demand forecast is greater than or equal to yesterday's closing inventory) be y[(i, d)]? Assuming stuff you order cannot be used to satisfy demand in the same day, when demand exceeds previous day's inventory you use up all of the previous day's inventory filling demand, drop the excess demand and end up with inventory containing any new orders arriving that day.

$\endgroup$
3
  • $\begingroup$ Thanks a lot, professor, changed constraint 3, and the model ran to optimality. Constraint 5 looks ok to you to deal with perishable days ? $\endgroup$ Nov 2, 2022 at 16:51
  • 1
    $\begingroup$ No idea. It might be easier to tell if your model were written out in algebraic notation and all variables/parameters were explicitly defined. $\endgroup$
    – prubin
    Nov 2, 2022 at 18:00
  • $\begingroup$ Edited the post above, model is still infeasible $\endgroup$ Nov 2, 2022 at 19:18
1
$\begingroup$

It seems you would need to tweak the mentioned model to be close to the standard Multi item-Multi period lot-sizing problem. The following formulation can give you some good starting points.

\begin{array} \text{Min} \quad \mathbb{Z} = \sum_i \sum_t s_{i,t} \\ \text{S.t:} \\ s_{i,t-1} + x_{i,t} = D_{i,t} + s_{i,t} \quad \forall i,t & (1)\\ s_{i,0} = SS_{i,0} \quad \forall i & (2)\\ s_{i,t} \geq SS_{i,t} \quad \forall i,t & (3)\\ x_{i,t} \leq M_{i,t}.y_{i,t} \quad \forall i,t & (4)\\ x_{i,t}, s_{i,t} \in \mathbb{R}_{+}, y_{i,t} \in\{0,1\} \quad \forall i,t & (5)\\ \end{array}

where, $x_{i,t}$ represents the amount of product $i$ produced during time period $t$, $y_{i,t}$ is the switching to produce a batch, $s_{i,t}$ represents the inventory level of product $i$ at the end of the time period $t$. Also, $SS_{i,t}$ represents the initial stock of item $i$ at the beginning of the planning horizon that can be assumed to be zero, and $D_{i,t}$ is the demand forecast.

Now, one possible way to capture the perished inventory constraint is to define the new auxiliary variable $ps_{i,t} \in \mathbb{R}_{+}$, adding this constraint $ps_{i,t} = \max(0, s_{i,t+t^{'}}-s_{i,t})$ that $t^{'}$ is fixed number of days to perish, and its appropriate penalty in the objective function. I think actually the above model does not allow to produce the excess inventory.

$\endgroup$
6
  • $\begingroup$ From this model are we suggesting, eod inventory at any given day (which is a variable) has to be >= a pre-specified number ( SS(i,t) here ) . For perishable i added a constraint I(i,d+shelf_life) <= (1-x(i,d))*M $\endgroup$ Nov 4, 2022 at 4:39
  • $\begingroup$ I modelled inventory equation as below from 2nd day onwards and it worked.. ``` I[(i,d)] == I[(i,d-1)] - dmd_forecast[(i,d)] + y[(i,d)] - y[(i,max(241,d-shelf_days[i]))] ``` $\endgroup$ Nov 4, 2022 at 7:11
  • $\begingroup$ @ShilpiBhargava, actually NO. It, (SS), is just a safety level and you can already assume it as zero. $\endgroup$
    – A.Omidi
    Nov 4, 2022 at 7:12
  • $\begingroup$ @ShilpiBhargava, standard way to model a smooth inventory control is to use mentioned constraint. Actually you can add other things to get what you want. :) $\endgroup$
    – A.Omidi
    Nov 4, 2022 at 7:18
  • $\begingroup$ @A.Omidi just out of curiosity, is this a problem studied in the literature? Isn't it just an uncapacitated lot sizing problem for each item? The problem seems to decompose into a problem per item, no? $\endgroup$
    – Sune
    Nov 4, 2022 at 20:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.