LP生产规划中生产线换产时间约束的建模求解问题
生产优化LP(MILP)换产逻辑建模方案
纯连续变量的线性规划无法直接表达“是否发生切换”这类离散逻辑,必须补充少量0-1二元变量转为混合整数线性规划(MILP)求解,你这个场景规模很小,常规开源求解器就能秒出结果,具体建模方式如下:
核心变量定义
两条生产线逻辑完全一致,按「生产线-日期-产品」三个维度定义变量即可:
- 连续变量
x[l][t][p]:生产线l在第t天生产产品p的有效生产时长,单位为小时 - 0-1二元变量
y[l][t][p]:标记生产线l在第t天是否生产过产品p,1为生产、0为未生产 - 0-1二元变量
z[l][t]:标记生产线l在第t天是否发生产品切换,1为发生切换、0为未发生 - 连续变量
s[t][p]:第t天结束时产品p的库存余量,单位为吨 - 固定参数:生产线生产效率
rate[l],1号线满负荷24小时产10吨,取值10/24吨/小时;2号线满负荷24小时产8吨,取值8/24吨/小时
约束搭建
1. 换产时间扣减约束
直接对应你给出的换产扣2小时的规则:当日发生1次切换就从满负荷24小时里扣2小时可用生产时长,和你举的“生产a再切b,当日可用22小时”的示例完全匹配:
sum( x[l][t][p] for p in 生产线l可生产的产品集合 ) <= 24 - 2 * z[l][t]
如果后续需要支持单日多次切换(比如a→b→c扣4小时),只需要把z[l][t]改成非负整数变量,调整后续触发逻辑即可,框架不用动。
2. 换产行为触发约束
首先绑定生产标记和生产时长的关系:只要某天花了大于0的时间生产某产品,对应的生产标记必须为1,用大M法实现即可(M取常数24,为单日最大可能生产时长):
x[l][t][p] <= 24 * y[l][t][p] // 对所有l、t、对应可生产的p生效
其次绑定切换标记和生产行为的关系:单日只要生产2种及以上产品,必然触发至少1次切换:
sum( y[l][t][p] for p in 生产线l可生产的产品集合 ) - 1 <= z[l][t]
如果需要把跨天切换(比如前一天最后生产a,当天开场生产b)也计入换产,只需要新增一组0-1变量标记每日生产线最后生产的产品,加一条判定前后天收尾/开场产品不一致时z[l][t]加1即可,日粒度排程如果不要求严格的生产顺序衔接,初期可以先不做这层,等基础模型跑通再补。
3. 库存与需求满足硬约束
库存按日流转,不允许缺货:
// 期初库存取给定初始值:s[0][a]=3, s[0][b]=2, s[0][c]=3, s[0][d]=0 s[t][p] = s[t-1][p] + sum( x[l][t][p] * rate[l] for l in 可生产p的生产线集合 ) - demand[t][p] s[t][p] >= 0 // 所有日期、所有产品的期末库存不能为负
4. 换产频率软约束
“每3天换产不超过1次”不需要做硬限制,在目标函数里加惩罚项即可:
- 新增连续松弛变量
violate[l][t],表示3天窗口内的换产超额次数 - 加约束:
sum( z[l][t-k] for k in 0,1,2 ) <= 1 + violate[l][t](t>=3时生效) - 目标函数里给
violate设置一个较高的惩罚权重,求解器就会优先选择不违反换产频率的排程,遇到必须换产才能满足需求的场景也不会直接判定模型无解。
目标函数
核心目标为产量最大化,同时减去软约束的惩罚项:
max( sum( x[l][t][p] * rate[l] for all l,t,p ) - penalty * sum( violate[l][t] for all l,t ) )
落地提示
- 月度30天、2条线、4个产品的规模非常小,不管是开源求解器(HiGHS、CBC)还是商用求解器都能在几秒内算出结果
- 如果需要输出更细粒度的“各时段排程”,只需要把日维度拆成小时/半小时的时间块,变量和约束逻辑完全复用,不需要改框架
内容的提问来源于stack exchange,提问作者Stepan SSSD
相关产品推荐
相关产品推荐

