CPLEX定义二元对集合R及编写zij、f对应约束的方法
CPLEX OPL 集合定义与约束编写实现
你已完成f变量声明,剩余部分按以下步骤编写即可:
1. 二元组集合R定义
OPL中通过tuple结构实现二元组,再基于tuple声明集合R即可,根据R的生成逻辑二选一:
- 若R是
channels集合上满足特定规则的所有二元组(例如排除i=j的配对):
// 先定义二元组结构 tuple ChannelPair { int i; int j; } // 按规则生成集合R,示例为所有i不等于j的通道对,可按需修改筛选条件 {ChannelPair} R = {<i,j> | i in channels, j in channels: i != j};
- 若R是提前确定的固定二元组列表,直接枚举即可:
tuple ChannelPair { int i; int j; } {ChannelPair} R = {<1,2>, <2,4>, <3,1>}; // 替换为你实际需要的配对
2. 0-1变量z声明
zij是定义在R上的二元变量,直接对应集合声明即可,声明后自动满足zij ∈ {0,1}的域约束,无需额外写约束:
dvar boolean z[R];
3. 常量参数定义
先声明提到的两个参数,按实际业务场景赋值即可:
float E = 1e-6; // 极小正数,按需调整大小 int M = 10000; // 足够大的常数,需大于f数组任意两元素的最大可能差值
4. 约束编写
在subject to块中遍历R集合写约束即可,两种等价写法任选其一:
- 写法1(解构tuple元素,可读性更高):
subject to { forall(<i,j> in R) { f[j] - f[i] >= -M*(1 - z[<i,j>]); f[i] - f[j] >= E - M*z[<i,j>]; } }
- 写法2(直接引用tuple元素):
subject to { forall(p in R) { f[p.j] - f[p.i] >= -M*(1 - z[p]); f[p.i] - f[p.j] >= E - M*z[p]; } }
注意事项:M取值不要盲目设得极大,只要能覆盖f的最大可能差值即可,过大的M会降低模型数值稳定性,导致求解速度变慢甚至出现求解误差。
内容的提问来源于stack exchange,提问作者MO MO MA
相关产品推荐
相关产品推荐

