R&D · 14 июня 2026 г. · 12 мин
Сколько держать на складе? Считает модель, а не правило Уилсона
Целочисленная модель запасов: хранение vs дефицит, lead time, MOQ. На машиностроительном холдинге излишки −32%.
Аксенов Юрий Васильевич
Руководитель ГК «ФОРОНЕЙ»
Коротко
EOQ Уилсона ломается, когда спрос скачет и поставка едет не в тот день. Тогда это MILP: целые партии, задержка, штраф за дыру на сборке.
Пусть I_t запас на конец дня, X_t заказ, d_t спрос, h хранение, p штраф дефицита, L lead time.
min ∑ (h · I_t + p · shortage_t)
I_t = I_{t-1} + X_{t-L} − sales_t
X_t ≥ 0, кратно MOQ
Решатель
import gurobipy as gp
from gurobipy import GRB
m = gp.Model("Inventory_Optimization")
T = 30
demand = [120, 150, 100, 90, 110, 130] * 5
h, p, lead_time = 5.0, 50.0, 3
X = m.addVars(T, vtype=GRB.INTEGER, name="Order_Qty")
I = m.addVars(T, vtype=GRB.CONTINUOUS, name="Inventory_Level")
shortage = m.addVars(T, vtype=GRB.CONTINUOUS, name="Shortage")
for t in range(T):
prev_inv = I[t - 1] if t > 0 else 100
order_arrival = X[t - lead_time] if t >= lead_time else 0
m.addConstr(I[t] == prev_inv + order_arrival - demand[t] + shortage[t])
m.addConstr(X[t] >= 0)
m.setObjective(gp.quicksum(h * I[t] + p * shortage[t] for t in range(T)), GRB.MINIMIZE)
m.optimize()
Что вышло
На логистике машиностроительного холдинга излишки уехали на 32%. Останов цеха из-за пустой ячейки на горизонте модели свели к нулю. Считали конкретный горизонт, MOQ и штраф, которые заказчик подписал.