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

Pulp优化工具中实现选中SKU品类数不超过指定值的约束设置问题

解决方案

你之前写的约束无法生效的原因是:df['SKU'].count(distinct)是统计数据集固定的SKU总数,和优化变量的取值没有关联,自然不会对求解结果产生限制。
要实现「选中的SKU品类总数不超过500」的约束,需要引入二进制辅助变量标记SKU是否被选中,具体实现步骤如下:

  1. 定义二进制辅助变量:为每行对应的SKU定义一个0-1变量y[idx],取值为1时代表该SKU被选中,取值为0时代表未被选中。
  2. 绑定原变量和辅助变量的关联:加约束规则,如果某SKU的分配量x[idx]>0,则对应的y[idx]必须为1;如果y[idx]=0,则该SKU的分配量必须为0。
  3. 新增SKU总数约束:所有二进制变量的总和≤500,即为你需要的品类数限制。

完整修改后的代码示例

import pandas as pd
import pulp

# 你原有的读取数据代码
df=pd.read_excel(ruta+"actual/202109.xlsx", nrows=20) 
max_uni = 你原有定义的最大单位数 # 请补充你自己定义的max_uni赋值

# 创建变量和模型
x = pulp.LpVariable.dicts("x", df.index, lowBound=0)
# 新增:二进制辅助变量,标记SKU是否被选中
y = pulp.LpVariable.dicts("y", df.index, cat='Binary')
mod = pulp.LpProblem("Budget", pulp.LpMaximize)

# 目标函数(和你原来的逻辑一致)
objvals = {idx: (1.0)*(df['costo_unitario'][idx]) for idx in df.index}
mod += sum([x[idx]*objvals[idx] for idx in df.index])

# 原有上下界约束修改:绑定x和y的关系
for idx in df.index:
    # 当y[idx]为0时,x[idx]只能取0;y[idx]为1时,x[idx]上限为最大库存
    mod += x[idx] <= df['unidades_sobrestock'][idx] * y[idx]

# 原有总库存预算约束(保持不变)
mod += sum([x[idx] for idx in df.index]) <= max_uni

# 新增:选中SKU总数不超过500的约束
mod += sum([y[idx] for idx in df.index]) <= 500

# 求解模型
mod.solve()

# 输出结果
for idx in df.index:
    print(f"{idx} 分配量:{x[idx].value()},是否选中SKU:{y[idx].value()}")

print(f"目标值:{pulp.value(mod.objective)}")

特殊情况说明

如果你的数据框中存在同一个SKU对应多行记录的情况,需要先按SKU编号分组,为每个唯一SKU定义一个二进制变量,再把该SKU下所有行的x变量和同一个y变量绑定即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 03:36:04