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

Scipy Minimize建模报错求助:双门店周需求分配线性约束问题

Scipy Minimize非线性优化问题排查

问题背景

  • 两家门店,已知某产品全年52周总需求,需将年度需求分配到两家门店,确定各门店每周供应量
  • 目标:最小化全年未满足的总需求
  • 变量:前52个变量为门店1周供应量,后52个为门店2周供应量
  • 目标函数:每周未满足需求之和(即Σmax(0, 当周总需求 - 门店1供应量 - 门店2供应量))
  • 约束1:每周两家门店供应量之和 ≤ 当周总需求

代码中的错误分析

  1. 变量名不一致:定义了weeks = 52,但循环创建约束时用了未定义的semanas,会触发NameError
  2. Lambda闭包陷阱:循环中创建的lambda函数会共享同一个i变量,最终所有约束都会使用循环最后一次的i值(51),导致约束逻辑完全错误
  3. 目标函数逻辑错误:当前直接计算total[i] - x[i] - x[i+52]的总和,当供应量超过需求时会得到负数,这与“未满足需求”的定义矛盾(未满足需求不能为负)
  4. 初始值不合理: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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 20:36:17