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

请求排查CPLEX求和约束错误:二进制变量x求和约束问题

排查CPLEX中二进制变量x的求和约束错误

我帮你梳理下最后那条ctWorkOneShiftPerDay约束的问题,核心问题出在变量嵌套和逻辑范围上:

  • 变量冲突导致逻辑偏离:你在forall(w in worker, i in part, h in period)的外层循环里已经用了i作为遍历变量,结果内层求和又写了sum (i in part)——这会让CPLEX把内层的i当成全新的局部变量,等于给每个工人、每个零件、每个周期都重复计算了一次所有零件的x值之和,完全不符合你“每个工人每天只做一种零件”的需求。
  • 逻辑范围错误:从约束名称能看出来,你想限制的是每个工人在单个周期内,最多只能分配到一种零件的工作,所以遍历范围应该是每个工人+每个周期,不需要把零件i放到外层的forall里。

修正后的约束代码

把原约束调整成下面这样,就符合你的业务逻辑了:

ctWorkOneShiftPerDay: forall(w in worker, h in period) {
    sum (i in part) x[w, i, h] <= 1;
}

额外的优化提示

顺便提一下ctworkHrperPeriod约束的小问题:
你现在写的是:

ctworkHrperPeriod: forall (w in worker,i in part, h in period) {
    workHr[w, h] >= 10.50 + 100000000 * (1 - x[w, i, h]);
    workHr[w, h] <= 10.50 - 100000000 * (1 - x[w, i, h]);
}

这个写法等价于:当x[w,i,h] = 1时,workHr[w,h]必须等于10.50;但如果没修正前面的约束,一个工人在某天被分配到多个零件的话,这里会直接导致矛盾(要求workHr同时等于10.50多次,逻辑冲突)。修正完ctWorkOneShiftPerDay后,每个工人每天最多只有一个x[w,i,h]为1,这个约束就能正常生效了。

另外,建议把那个超大的M值100000000定义成一个常量,比如:

const float BIG_M = 1e8;

然后在约束里用BIG_M代替硬编码的数字,这样代码可读性更高,后续调整也更方便。

内容的提问来源于stack exchange,提问作者Khải Duy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 04:27:13