在CPLEX中如何使用向量元素定义变量遍历的动态range范围?
CPLEX动态遍历范围正确定义方案
你原先的range I = 1..nj属于无效语法:首先nj是数组而非单个整数,其次CPLEX的range关键字仅支持绑定固定静态的整数上下界,无法直接适配随j变化的i动态范围。
根据你的需求(对每个j∈J,i的遍历范围为1到nj对应位置的元素值),有两种常用实现方式:
方法1:预定义合法元组集合(适用需要统一调用范围的场景)
先构造包含所有合法(j,i)对的集合,后续定义变量、写约束时直接遍历该集合即可:
// 第一步:定义基础索引J range J = 1..7; // 第二步:定义nj数组 int nj[J] = [1, 4, 5, 6, 9, 3, 10]; // 第三步:构造所有合法(j,i)对的集合 tuple Pair { int j; int i; } {Pair} validPairs = {<j,i> | j in J, i in 1..nj[j]};
使用示例:
// 定义对应维度的变量 dvar boolean x[validPairs]; // 约束中遍历 subject to { forall(<j,i> in validPairs) { x[<j,i>] <= 1; } }
方法2:遍历j时动态指定i范围(适用无需提前复用范围的场景)
不需要提前定义统一集合,直接在变量声明、约束编写时嵌套遍历即可:
range J = 1..7; int nj[J] = [1, 4, 5, 6, 9, 3, 10]; // 定义第二维随j动态变化的变量 dvar int+ x[j in J][1..nj[j]]; // 约束中直接嵌套遍历 subject to { forall(j in J, i in 1..nj[j]) { x[j][i] <= nj[j]; } }
注意事项
- 代码定义顺序不能乱:必须先定义
J,再声明nj数组,才能在后续逻辑中调用nj[j]作为范围上界 - 动态范围不能直接赋值给
range类型的变量,仅能在集合推导、变量维度声明、forall遍历的范围表达式中使用
内容的提问来源于stack exchange,提问作者Francesca
相关产品推荐
相关产品推荐

