CPLEX中如何基于已定义数组生成符合规则的新数组
CPLEX中实现按规则生成重复元素数组的方法
针对初始数组[1,3,2,5],按「原数组元素值等于该元素在新数组中连续重复次数」的规则生成目标数组[1,3,3,3,2,2,5,5,5,5,5],可以根据你使用CPLEX的场景选择对应实现方式:
OPL建模实现(CPLEX Studio原生场景)
这是最常用的建模场景,直接在OPL中预计算生成目标参数数组即可,不需要引入额外决策变量:
- 首先定义初始数组,计算目标数组总长度:目标数组总长度等于初始数组所有元素的和,示例中1+3+2+5=11,和目标数组长度完全匹配
- 其次计算原数组每个元素在目标数组中的起始偏移位置,按位置范围批量赋值
完整可运行代码如下:
// 定义初始输入数组 int initArr[] = [1,3,2,5]; // 计算目标数组总长度 int targetLength = sum(idx in indices(initArr)) initArr[idx]; // 声明目标数组 int targetArr[1..targetLength]; // 计算每个原元素在目标数组的起始下标 int startPos[idx in indices(initArr)] = (idx == 0) ? 1 : startPos[idx-1] + initArr[idx-1]; // 脚本块执行赋值 execute { for(var i in indices(initArr)) { var curVal = initArr[i]; var rangeStart = startPos[i]; var rangeEnd = rangeStart + curVal - 1; for(var p = rangeStart; p <= rangeEnd; p++) { targetArr[p] = curVal; } } // 打印验证结果,输出为 [1 3 3 3 2 2 5 5 5 5 5] writeln("生成的目标数组:", targetArr); }
如果不想使用脚本块,也可以通过辅助二元变量加约束的方式隐式定义目标数组,但这种方式会额外增加决策变量规模,对于固定参数的数组生成,预计算赋值的效率更高。
API调用实现(Python/Java/C++等接口场景)
如果是通过编程语言调用CPLEX API搭建模型,不需要依赖OPL语法,直接在宿主代码中生成目标数组,再作为参数传入CPLEX模型即可。
以Python API为例,数组生成代码非常简洁:
init_arr = [1,3,2,5] target_arr = [] for num in init_arr: # 将当前元素按取值次数重复追加到目标数组 target_arr.extend([num] * num) # 验证输出:print(target_arr) -> [1, 3, 3, 3, 2, 2, 5, 5, 5, 5, 5]
注意:使用前需要校验初始数组的元素值,若存在0或负数会导致重复次数非法,需要提前做异常处理。
内容的提问来源于stack exchange,提问作者MO MO MA
相关产品推荐
相关产品推荐

