基于Python+Gurobi的库存分配问题建模求解
库存分配问题(Inventory Allocation Problem)是供应链管理中的一个经典问题,主要研究如何将有限的库存资源合理地分配给多个需求点(如客户、零售商或分销中心),以优化某些目标(如最小化成本、最大化服务水平等)。库存分配问题只需关注何时向哪些客户配送多少货物
数学模型
参数
- T T T:时间周期集合。
- N N N:客户集合。
- d i t d_{it} dit:客户 i i i 在时间 t t t 的需求。
- h i h_i hi:客户 i i i 的单位库存持有成本。
- c i c_i ci:从供应商到客户 i i i 的单位运输成本。
- S i S_i Si:客户 i i i 的库存容量。
- I i 0 I_{i0} Ii0:客户 i i i 的初始库存。
- S 0 S_0 S0:供应商的库存容量。
- I 00 I_{00} I00:供应商的初始库存。
决策变量
- y i t y_{it} yit:在时间 t t t 向客户 i i i 配送的货物量。
中间变量
- I i t I_{it} Iit:客户 i i i 在时间 t t t 的库存水平。
- I 0 t I_{0t} I0t:供应商在时间 t t t 的库存水平。
目标函数:最小化总成本(库存持有成本 + 运输成本):
min ∑ t ∈ T ( ∑ i ∈ N h i I i t + ∑ i ∈ N c i y i t ) \min \sum_{t \in T} \left( \sum_{i \in N} h_i I_{it} + \sum_{i \in N} c_i y_{it} \right) mint∈T∑(i∈N∑hiIit+i∈N∑ciyit)
约束条件
-
客户库存平衡:
I i t = I i , t − 1 + y i t − d i t , ∀ i ∈ N , t ∈ T I_{it} = I_{i,t-1} + y_{it} - d_{it}, \quad \forall i \in N, t \in T Iit=Ii,t−1+yit−dit,∀i∈N,t∈T -
供应商库存平衡:
I 0 t = I 0 , t − 1 − ∑ i ∈ N y i t , ∀ t ∈ T I_{0t} = I_{0,t-1} - \sum_{i \in N} y_{it}, \quad \forall t \in T I0t=I0,t−1−i∈N∑yit,∀t∈T -
客户库存容量:
0 ≤ I i t ≤ S i , ∀ i ∈ N , t ∈ T 0 \leq I_{it} \leq S_i, \quad \forall i \in N, t \in T 0≤Iit≤Si,∀i∈N,t∈T -
供应商库存容量:
0 ≤ I 0 t ≤ S 0 , ∀ t ∈ T 0 \leq I_{0t} \leq S_0, \quad \forall t \in T 0≤I0t≤S0,∀t∈T -
配送量非负:
y i t ≥ 0 , ∀ i ∈ N , t ∈ T y_{it} \geq 0, \quad \forall i \in N, t \in T yit≥0,∀i∈N,t∈T
代码实现
from gurobipy import Model, GRB
# 参数设置
T = range(1, 5) # 时间周期,例如 4 个周期
N = ["C1", "C2"] # 客户集合
d = {
("C1", 1): 10,
("C1", 2): 20,
("C1", 3): 15,
("C1", 4): 25, # 客户需求
("C2", 1): 15,
("C2", 2): 10,
("C2", 3): 20,
("C2", 4): 15,
}
h = {"C1": 1, "C2": 1} # 客户单位库存持有成本
c = {"C1": 5, "C2": 7} # 从供应商到客户的单位运输成本
S = {"C1": 100, "C2": 100} # 客户库存容量(放宽容量)
S0 = 200 # 供应商库存容量(放宽容量)
I0 = {"C1": 50, "C2": 50} # 客户初始库存(增加初始库存)
I00 = 100 # 供应商初始库存(增加初始库存)
# 创建模型
model = Model("Inventory_Allocation_Problem")
# 决策变量
y = model.addVars(N, T, name="Delivery") # 配送量
I = model.addVars(N, T, name="Inventory") # 客户库存水平
I_supplier = model.addVars(T, name="Supplier_Inventory") # 供应商库存水平
# 目标函数
model.setObjective(
sum(h[i] * I[i, t] for i in N for t in T)
+ sum(c[i] * y[i, t] for i in N for t in T),
sense=GRB.MINIMIZE,
)
# 约束条件
for i in N:
for t in T:
# 客户库存平衡约束
if t == 1:
model.addConstr(
I[i, t] == I0[i] + y[i, t] - d[i, t], name=f"Balance_{i}_{t}"
)
else:
model.addConstr(
I[i, t] == I[i, t - 1] + y[i, t] - d[i, t], name=f"Balance_{i}_{t}"
)
# 客户库存容量约束
model.addConstr(I[i, t] <= S[i], name=f"Capacity_{i}_{t}")
for t in T:
# 供应商库存平衡约束
if t == 1:
model.addConstr(
I_supplier[t] == I00 - sum(y[i, t] for i in N), name=f"Supplier_Balance_{t}"
)
else:
model.addConstr(
I_supplier[t] == I_supplier[t - 1] - sum(y[i, t] for i in N),
name=f"Supplier_Balance_{t}",
)
# 供应商库存容量约束
model.addConstr(I_supplier[t] <= S0, name=f"Supplier_Capacity_{t}")
# 求解模型
model.optimize()
# 输出结果
if model.status == GRB.OPTIMAL:
print("Optimal solution found!")
print(f"Total Cost = {model.objVal}")
print("\nDelivery Plan:")
for i in N:
for t in T:
print(f"Delivery to {i} at time {t}: {y[i, t].X}")
print("\nCustomer Inventory Levels:")
for i in N:
for t in T:
print(f"Inventory of {i} at time {t}: {I[i, t].X}")
print("\nSupplier Inventory Levels:")
for t in T:
print(f"Supplier Inventory at time {t}: {I_supplier[t].X}")
else:
print("No optimal solution found.")
if model.status == GRB.INFEASIBLE:
print("Model is infeasible. Check constraints and parameters.")
打印结果:
Set parameter Username
Set parameter LicenseID to value 2583232
Academic license - for non-commercial use only - expires 2025-11-13
Gurobi Optimizer version 12.0.0 build v12.0.0rc1 (win64 - Windows 11+.0 (27774.2))
CPU model: 11th Gen Intel(R) Core(TM) i5-1135G7 @ 2.40GHz, instruction set [SSE2|AVX|AVX2|AVX512]
Thread count: 4 physical cores, 8 logical processors, using up to 8 threads
Optimize a model with 24 rows, 20 columns and 49 nonzeros
Model fingerprint: 0x9b8bbd90
Coefficient statistics:
Matrix range [1e+00, 1e+00]
Objective range [1e+00, 7e+00]
Bounds range [0e+00, 0e+00]
RHS range [1e+01, 2e+02]
Presolve removed 17 rows and 8 columns
Presolve time: 0.00s
Presolved: 7 rows, 12 columns, 22 nonzeros
Iteration Objective Primal Inf. Dual Inf. Time
0 1.2994100e+02 3.761750e+00 0.000000e+00 0s
6 3.0000000e+02 0.000000e+00 0.000000e+00 0s
Solved in 6 iterations and 0.00 seconds (0.00 work units)
Optimal objective 3.000000000e+02
Optimal solution found!
Total Cost = 300.0
Delivery Plan:
Delivery to C1 at time 1: 0.0
Delivery to C1 at time 2: 0.0
Delivery to C1 at time 3: 0.0
Delivery to C1 at time 4: 20.0
Delivery to C2 at time 1: 0.0
Delivery to C2 at time 2: 0.0
Delivery to C2 at time 3: 0.0
Delivery to C2 at time 4: 10.0
Customer Inventory Levels:
Inventory of C1 at time 1: 40.0
Inventory of C1 at time 2: 20.0
Inventory of C1 at time 3: 5.0
Inventory of C1 at time 4: 0.0
Inventory of C2 at time 1: 35.0
Inventory of C2 at time 2: 25.0
Inventory of C2 at time 3: 5.0
Inventory of C2 at time 4: 0.0
Supplier Inventory Levels:
Supplier Inventory at time 1: 100.0
Supplier Inventory at time 2: 100.0
Supplier Inventory at time 3: 100.0
Supplier Inventory at time 4: 70.0
原文地址:https://blog.csdn.net/qq_43276566/article/details/145217040
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!