CP Optimizer:带最小值0的cumul函数减去时变值的实现方法
解决方案:在CP模型中计算优先使用A物料后的B类剩余需求
核心思路
要实现优先使用A类物料,剩余需求由B类承担且保证B类需求非负,关键是先定义实际消耗的A类物料量aUsage,确保它既不超过A的供应量,也不超过总需求,再通过总需求减去实际A消耗量得到B的需求。
1. 将时变的A类供应量转换为cumulFunction
先把数组形式的supplyA转换成CP模型中的cumulFunction,用来表示每个时间点的A物料可用量。假设supplyA的3个元素对应时间区间[0,1)、[1,2)、[2,3),对应定义如下:
int supplyA[h in 1..3] = [5, 100, 5]; // 构造supplyA的cumulFunction:0-1时段供应5,1-2时段供应100,2-3时段供应5,3之后供应0 cumulFunction supplyA_cumul = step(0, supplyA[1]) + step(1, supplyA[2] - supplyA[1]) + step(2, supplyA[3] - supplyA[2]) + step(3, -supplyA[3]);
2. 定义实际消耗的A类物料量aUsage
通过约束保证aUsage不超过A的供应量与总需求,并最大化aUsage的总消耗量,以此实现优先使用A物料的逻辑:
cumulFunction rUsage = sum(m in Modes) pulse(mode[m], m.dmdR); cumulFunction aUsage; // 约束1:实际消耗的A物料不能超过对应时间点的A供应量 always(aUsage <= supplyA_cumul); // 约束2:实际消耗的A物料不能超过对应时间点的总需求 always(aUsage <= rUsage); // 目标:最大化A物料的总消耗量,确保优先使用A maximize integral(aUsage);
3. 推导B类物料的剩余需求bUsage
直接通过总需求减去实际A消耗量得到B的需求,天然保证非负(因为aUsage ≤ rUsage):
cumulFunction bUsage = rUsage - aUsage;
为什么之前的方法失效?
如果仅用额外区间变量建模A物料消耗,容易陷入"必须完全占用供应区间"的误区,无法灵活处理A供应量超过总需求的场景。而通过cumulFunction的约束+最大化A消耗量的目标,既能保证A的使用不超标,又能自动适配"需求小于供应时,只取需求的量"的情况。
内容的提问来源于stack exchange,提问作者Hajo Terbrack
相关产品推荐
相关产品推荐

