CPLEX中不同j下标对应不同i取值范围的约束编写方法
CPLEX OPL不同j对应差异化i取值范围的约束实现方案
以下是三种适配该场景的实现方式:
方法1:按j单独限定i范围(性能最优)
- 先定义每个j对应的i上限数组,存储每个j允许的最大i值
int num_j = 3; range J = 1..num_j; // 按需求赋值每个j的i最大取值,也可从.dat文件导入 int max_i[J] = [10, 3, 7]; range M = 1..你的M维度大小; dvar boolean y[1..max(max_i), J, M];
- 调整遍历顺序,先遍历j再取对应i范围生成约束
forall(j in J) forall(i in 1..max_i[j]) constraint_1: sum(m in M) y[i][j][m] == 1;
该方式不会生成无效迭代,运行效率最高,是最推荐的写法
方法2:循环增加过滤条件(适配固定遍历顺序场景)
如果逻辑上必须先遍历i,可以在j的循环中加条件过滤合法的(i,j)对:
int num_j = 3; range J = 1..num_j; int max_i_all = 10; // 所有j的i最大取值 range I_all = 1..max_i_all; int max_i[J] = [10, 3, 7]; range M = 1..你的M维度大小; dvar boolean y[I_all, J, M]; forall(i in I_all) // 仅当i在当前j的合法取值范围内时,才生成对应约束 forall(j in J: i <= max_i[j]) constraint_1: sum(m in M) y[i][j][m] == 1;
进阶优化:预定义合法(i,j)元组集合
如果需要减少变量存储开销,可以提前定义所有合法的(i,j)对集合,变量仅在合法对上声明:
tuple IJPair { int i; int j; } // 批量生成所有合法(i,j)对 {IJPair} valid_ij = {<i,j> | j in J, i in 1..max_i[j]}; // 变量仅在合法(i,j)对上定义,大幅降低内存占用 dvar boolean y[valid_ij][M]; // 约束直接遍历合法集合即可 forall(<i,j> in valid_ij) constraint_1: sum(m in M) y[<i,j>][m] == 1;
内容的提问来源于stack exchange,提问作者Francesca
相关产品推荐
相关产品推荐

