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

CPLEX OPL约束未生效:决策变量c未被限制为小于等于元组集s对应值

问题根因
  • 执行顺序不符合OPL运行规则:OPL会优先完成模型声明、约束生成,最后才执行execute脚本块。你在subject to约束块中计算card(s)时,s还没被脚本填充,是空集,此时card(s)=0,对应的forall循环没有任何迭代,根本不会生成约束,自然约束不生效。
  • 约束逻辑错误:即便s提前填充完成,你写的双重循环forall( k in w, i in 1.. card(s) )会给每个c[k]叠加所有s元素的value上限,最终所有c都会被限制为小于等于s中的最小值1,和你「每个c[k]仅对应s中同位置value上限」的需求完全不符。
  • 元组取值逻辑错误:item(s,<i>)是按元组定义的key字段做匹配查找,你的元组key是rank字段,不是元组在集合中的插入序号,哪怕s填充完成,这种写法也不能按位置取到对应元组。
修复方法
  1. 将元组集s的填充逻辑从后置execute块移到模型声明阶段,保证约束生成时s已经是填充完成的状态。
  2. 删掉错误的双重循环,直接遍历s中的元素,按元素的rank字段匹配c的索引添加上限约束即可。

修复后可运行的完整代码:

int n=4;
range r=1..n;
int m=11;
range w=1..m;

int a[r]=[1,3,2,5];

tuple t
{
  key int rank;
  int value;
}

// 声明阶段直接生成s,无需后置脚本填充
{t} s={ 
  <rank, a[i]> | i in r, j in 1..a[i], rank == sum(pre in 1..i-1) a[pre] + j 
};

// 按实际需求定义c的类型,整数变量用dvar int+,连续变量用dvar float+
dvar int+ c[w];

subject to 
{
  // 遍历s的每个元素生成对应约束
  forall( elem in s )
    c[elem.rank] <= elem.value;
}

execute
{
  // 可通过writeln打印s验证内容
  writeln("生成的元组集s:", s);
}
效果验证

上述代码生成的s内容为<1 1>, <2 3>, <3 3>, <4 3>, <5 2>, <6 2>, <7 5>, <8 5>, <9 5>, <10 5>, <11 5>,对应生成的约束完全匹配需求:

  • c[1] ≤ 1
  • c[2]、c[3]、c[4] ≤ 3
  • c[5]、c[6] ≤ 2
  • c[7]~c[11] ≤5

内容的提问来源于stack exchange,提问作者MO MO MA

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 23:45:46