I'm trying to optimize reorder quantities for $n$ products over $m$ periods in PuLP. The total reorder quantity should fill a container. I've never worked with multiple periods before, and I can't get it to work. I tried to formulate it the following way:
Minimize the sum over all ROQ (reorder quantity)
ROQ > 0
Inventory m+1 = Inventory m - demand m + ROQ m > 0
sum(ROQ n) m = container * trigger
I've created an integer trigger variable so I can order any quantity that's a multiple of a container, or nothing. It seemed relatively straightforward, but the solver keeps telling me the problem is infeasible to solve. I assume the problem is where I try to set next periods inventory as this periods inventory - demand + ROQ, because turning the equation around throws an error. I can't figure out how to overcome this problem. Can you point me in the right direction?
The formulation in pulp is:
import numpy as np import pandas as pd import random import pulp import warnings SKUs = 10 periods = 12 initial_inv = 50 container = 100 warnings.filterwarnings("ignore") df_DEM = pd.DataFrame(np.random.randint(0,200, size=(SKUs,periods))) df_INV = pd.DataFrame(np.random.randint(0,200, size=(SKUs,periods+1))) df_REP = pd.DataFrame(np.random.randint(0,1, size=(SKUs,periods))) problem = pulp.LpProblem('inventory', pulp.LpMinimize) #variables ROQ = pulp.LpVariable.dicts('ROQ', ((i, j) for i in range(SKUs) for j in range(periods)), lowBound=0, cat='Continuous') trigger = pulp.LpVariable.dicts('trigger', (i for i in range(periods)), cat='Integer') # set objective function problem += pulp.lpSum((ROQ[i,j]) for i in range(SKUs) for j in range(periods)) #constraints #1 ROQs > 0 for i in range(SKUs): for j in range(periods): problem += ROQ[i,j] >= 0 #2 trigger >= 0 for j in range(periods): problem += trigger[i] >= 0 #3 inventory in each period > 0 for i in range(SKUs): for j in range(periods): problem += df_INV.loc[i,j]-df_DEM.loc[i,j]+ROQ[i,j] >= 0 #4 inventory for the next period = inventory from this period + demand - reorder quantity for i in range(SKUs): for j in range(periods): problem += df_INV.loc[i,j] - df_DEM.loc[i,j] + ROQ[i,j] == df_INV.loc[i,j+1] #5 ROQ is in multiples of a container for j in range(periods): problem += pulp.lpSum(ROQ[i,j] for i in range(SKUs)) == trigger[j] * container # set solver options solver = pulp.PULP_CBC_CMD(fracGap=0.001, msg=True, warmStart=False) # solve problem status = problem.solve(solver) print(pulp.LpStatus[status], round(pulp.value(problem.objective),0))