You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python/PuLP构建库存不足时可行的运输线性规划模型

解决运输补货模型库存不足时的不可行问题

问题根源

你当前代码的核心问题是强制要求配送量等于门店需求(lpSum(...) == demand[s][i]),当总库存无法覆盖总需求时,模型必然无解。要实现“库存充足时100%满足需求,库存不足时耗尽库存并尽可能满足需求”,需要调整约束逻辑和目标函数。

修改方案

核心调整点:

  1. 放松需求约束:门店接收的商品量不能超过其需求,但无需强制等于需求;
  2. 调整目标函数:通过加权方式将“优先满足需求+最小化成本”的多目标转为单目标优化,确保先满足尽可能多的需求,再追求最低运输成本;
  3. 保留库存约束:仓库发出的商品量不能超过其库存(库存充足时可留余,库存不足时自动耗尽)。

修改后的完整代码

from pulp import *
import pandas as pd

# 仓库列表
warehouses = ["WHS_1","WHS_2","WHS_3"]

# 仓库-商品库存字典
inventory = {"WHS_1": {"SKU_A":50,"SKU_B":100},
             "WHS_2": {"SKU_A":50,"SKU_B":75} , 
             "WHS_3": {"SKU_A":150,"SKU_B":25} ,
            }

# 门店列表
stores = ["Store1","Store2"]

# 商品列表
items = ["SKU_A","SKU_B"]

# 门店-商品需求字典
demand = {
    "Store1": {"SKU_A":100,"SKU_B":250},
    "Store2": {"SKU_A":100,"SKU_B":50},
    }

# 仓库-门店-商品运输成本字典
costs =  {
          "WHS_1": {"Store1": {"SKU_A":10.50,"SKU_B":3.75},
                 "Store2": {"SKU_A":15.01,"SKU_B":5.15}},
          "WHS_2": {"Store1": {"SKU_A":9.69,"SKU_B":3.45},
                 "Store2": {"SKU_A":17.50,"SKU_B":6.06}},
          "WHS_3": {"Store1": {"SKU_A":12.12,"SKU_B":5.15},
                 "Store2": {"SKU_A":16.16,"SKU_B":7.07}},
            }

# 创建问题实例,目标为最小化
prob = LpProblem("StoreAllocation", LpMinimize)

# 生成所有可能的运输路线元组
routes = [(w, s, i) for w in warehouses for s in stores for i in items]
 
# 创建运输量变量,非负整数
vars = LpVariable.dicts("Route", (warehouses, stores, items), 0, None, LpInteger) 

# 目标函数:优先满足需求(用大权重惩罚未满足的需求),再最小化运输成本
# 权重设为100(远高于最高运输成本7.07),确保优先满足需求
demand_satisfaction = lpSum([vars[w][s][i] for (w, s, i) in routes])
transport_cost = lpSum([vars[w][s][i] * costs[w][s][i] for (w, s, i) in routes])
prob += transport_cost - 100 * demand_satisfaction, "Minimize_Cost_Maximize_Demand"

# 库存约束:仓库发出的商品量不能超过库存
for w in warehouses:
    for i in items:
        prob += (
            lpSum([vars[w][s][i] for s in stores]) <= inventory[w][i],
            f"Inventory_Limit_{w}_{i}",
        )

# 需求约束:门店接收的商品量不能超过其需求
for s in stores:
    for i in items:
        prob += (
            lpSum([vars[w][s][i] for w in warehouses]) <= demand[s][i],
            f"Demand_Limit_{s}_{i}",
        ) 

# 输出LP文件(可选)
prob.writeLP("TestProblem.lp")

# 求解模型
prob.solve()

# 输出结果
print("Status:", LpStatus[prob.status])
# 只打印有运输量的路线(更清晰)
for v in prob.variables():
    if v.varValue > 0:
        print(v.name, "=", v.varValue)
# 计算并打印实际满足的需求和真实运输成本
total_satisfied = sum(vars[w][s][i].varValue for w in warehouses for s in stores for i in items)
print(f"Total Satisfied Demand = {total_satisfied}")
# 还原真实成本:目标函数减去了加权项,需加回
print("Total Cost of Fulfillment = ", value(prob.objective) + 100 * total_satisfied)

关键修改说明

  1. 目标函数调整:
    加入需求满足量的加权项,用-100 * demand_satisfaction实现“优先满足需求”的优先级——因为权重远高于运输成本,模型会先尽可能多的满足需求,再在这个基础上寻找最低成本的运输方案。最后输出时需要还原真实运输成本(加回加权项的影响)。

  2. 约束调整:

    • 库存约束保留<=,允许库存充足时留余;
    • 需求约束从==改为<=,避免因库存不足导致无解,同时保证不会给门店配送超过需求的商品。

效果验证

  • 当库存充足时,模型会100%满足所有需求,同时输出最低运输成本;
  • 当库存不足时,模型会耗尽所有库存,尽可能满足需求,并输出该状态下的最低成本。

内容的提问来源于stack exchange,提问作者ctrlf_abalone

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 21:10:28