Scipy Minimize建模报错求助:双门店周需求分配线性约束问题
Scipy Minimize非线性优化问题排查
问题背景
- 两家门店,已知某产品全年52周总需求,需将年度需求分配到两家门店,确定各门店每周供应量
- 目标:最小化全年未满足的总需求
- 变量:前52个变量为门店1周供应量,后52个为门店2周供应量
- 目标函数:每周未满足需求之和(即
Σmax(0, 当周总需求 - 门店1供应量 - 门店2供应量)) - 约束1:每周两家门店供应量之和 ≤ 当周总需求
代码中的错误分析
- 变量名不一致:定义了
weeks = 52,但循环创建约束时用了未定义的semanas,会触发NameError - Lambda闭包陷阱:循环中创建的lambda函数会共享同一个
i变量,最终所有约束都会使用循环最后一次的i值(51),导致约束逻辑完全错误 - 目标函数逻辑错误:当前直接计算
total[i] - x[i] - x[i+52]的总和,当供应量超过需求时会得到负数,这与“未满足需求”的定义矛盾(未满足需求不能为负) - 初始值不合理:
x0设为固定值10000,若每周需求小于该值,初始点会直接违反约束,导致优化算法无法正常启动
修正后的代码
import numpy as np import pandas as pd from scipy.optimize import minimize weeks = 52 stores = 2 # 目标函数:最小化全年未满足总需求(仅计算非负部分) def objetivo(x, week, total): total_sum = 0.0 for i in range(week): unmet = total[i] - x[i] - x[i + weeks] # 未满足需求不能为负,取max(0, unmet) total_sum += max(0.0, unmet) return total_sum # 变量边界:供应量非负 b = (0.0, None) limites = b * (weeks * stores) # 初始值:按每周需求平均分配到两家门店,避免违反约束 x0 = [] for demand in uc['total'].values: x0.append(demand / 2) # 门店1初始供应量 x0.append(demand / 2) # 门店2初始供应量 x0 = np.array(x0) # 创建约束:使用闭包固定每个约束的i值 restricciones = [] for i in range(weeks): # 使用lambda的默认参数绑定当前i的值,避免闭包陷阱 restricciones.append({ 'type': 'ineq', 'fun': lambda x, i=i: uc['total'].values[i] - x[i] - x[i + weeks] }) # 执行优化 solucion = minimize( objetivo, x0, method='SLSQP', args=(weeks, uc['total'].values), bounds=limites, constraints=restricciones ) # 输出结果 print(solucion)
关键修正说明
- 统一变量名:用
weeks替代未定义的semanas,消除命名错误 - 解决闭包问题:给lambda添加默认参数
i=i,绑定循环时的当前i值,确保每个约束对应正确的周数 - 修复目标函数:添加
max(0.0, unmet),保证未满足需求非负,贴合实际业务逻辑 - 优化初始值:按每周需求平均分配到两家门店,确保初始点满足约束,让算法能正常启动
内容的提问来源于stack exchange,提问作者jean
相关产品推荐
相关产品推荐

