PuLP建模目标函数Excess语法报错及物料约束设置问题求助
PuLP线性规划代码问题排查与修正
存在的问题
- 初始Excess语法错误:最初写法中
(inv[m]+order[m]for m in material)是Python生成器对象,不能直接和求和结果做运算,必须用PuLP提供的lpSum()函数封装才能参与线性表达式计算。 - Excess逻辑错误:后续修正后的Excess是所有物料的全局总剩余值,后续
lpSum(Excess*cost[m]for m in material)相当于把全局总剩余重复乘以每个物料的成本再求和,完全不符合「单个物料过剩*对应成本再汇总」的过剩成本计算逻辑。 - 约束逻辑完全错误:
- 约束定义中外层循环变量
i和内层求和的循环变量i重名,会导致变量覆盖 - 当前约束是「所有产品的总物料消耗量 <= 所有物料的总库存+总采购量」,没有按单个物料维度校验,会出现某类物料耗尽但其他物料剩余很多时,约束仍判定合法的逻辑错误,不符合业务要求
- 约束定义中外层循环变量
- 语法细节错误:
- cost字典定义末尾多了多余的三个单引号
''',会引发语法报错 - 代码中存在HTML转义字符
"(应改为双引号)、<(应改为小于号)
- cost字典定义末尾多了多余的三个单引号
- 过剩值符号逻辑漏洞:当前Excess计算没有限制最小值为0,若某物料消耗量超过库存+采购量,会得到负的过剩值,加在最小化目标函数中会不合理地拉低总成本,导致模型得到错误的最优解。
修正后的完整代码
from pulp import LpVariable, LpProblem, LpMinimize, lpSum product = ['S1', 'S2'] material = ['A', 'B', 'C', 'D', 'E', 'F', 'I', 'G', 'H', 'J', 'K', 'L', 'M'] inv_bf = 40000 product_cost = {'S1': 4.28, 'S2': 4.28} usage = {'S1': {'A': 12.24, 'D': 12.24, 'E': 0.014, 'F': 0.095, 'G': 12.24, 'H': 0.589, 'J': 24.24, 'K': 0.005, 'L': 0.0105}, 'S2': {'A': 12.24, 'D': 12.24, 'E': 0.014, 'F': 0.095, 'G': 12.24, 'H': 0.589, 'J': 24.24, 'K': 0.005, 'L': 0.0105}} inv = {'A': 7645.8, 'B': 2470, 'C': 4526, 'D': 6678, 'J': 4180.92, 'G': 6879, 'E': 159.5, 'F': 717.4, 'I': 764.1, 'H': 1302.69, 'K': 248.79, 'L': 235, 'M': 179.4} cost = {'A': 0.03, 'B': 0.03, 'C': 0.056, 'D': 0.151, 'J': 0.024, 'G': 0.88, 'E': 5.156, 'F': 13.04, 'I': 11.09, 'H': 6.833, 'K': 11.261, 'L': 10.118, 'M': 11.914} # 定义变量 produce = LpVariable.dicts("produce", product, lowBound=0, cat='Integer') order = LpVariable.dicts("order", material, lowBound=0, cat='Integer') # 新增单个物料的过剩变量,限制非负 excess = LpVariable.dicts("excess", material, lowBound=0, cat='Continuous') # 初始化模型 model = LpProblem("total_cost", LpMinimize) # 目标函数 Total_ProCost = lpSum(product_cost[i] * produce[i] for i in product) Total_MatCost = lpSum(order[m] * cost[m] for m in material) Total_ExcessCost = lpSum(excess[m] * cost[m] for m in material) model.setObjective(Total_ProCost + Total_MatCost + Total_ExcessCost) # 约束1:每个物料的过剩=库存+采购-生产耗用,且过剩>=0(变量定义已限制) for m in material: # 计算该物料的总耗用量 total_usage = lpSum(produce[i] * usage[i][m] for i in product if m in usage[i]) model += excess[m] == inv[m] + order[m] - total_usage # 约束2:每个物料的生产耗用<=库存+采购(和约束1等价,也可只保留约束1) for m in material: total_usage = lpSum(produce[i] * usage[i][m] for i in product if m in usage[i]) model += total_usage <= inv[m] + order[m]
内容的提问来源于stack exchange,提问作者Kudadas
相关产品推荐
相关产品推荐

