如何在CPLEX中将现有代码改写为更简洁紧凑的写法?
CPLEX OPL代码紧凑优化方案
首先说明原代码存在两处可修正的问题:
- 逻辑判断错误:
macc [i][j] == 1 || 2 || 4 ...写法不生效,非布尔值的数字会被直接判定为true,导致多值匹配逻辑完全失效 - 变量引用错误:第一个分支的
y[i][j][m] == 1中m未定义,按照业务逻辑应为匹配macc[i][j]本身的下标值
最紧凑的实现方式
利用OPL的集合匹配和蕴含运算符,不需要嵌套if-else和多层循环,代码如下:
- 先在模型头部预定义匹配值集合:
fixedMSet = {1,2,4,5,7,11,12,13,14,15,16,17,18,19};
- 替换原有嵌套代码为两行约束:
forall(j in J, i in I1) (macc[i][j] in fixedMSet) => (y[i][j][macc[i][j]] == 1); forall(j in J, i in I1) (macc[i][j] == 3) => (y[i][j][3] == 1 || y[i][j][4] == 1);
优化点说明
- 合并两层嵌套
forall为多维度遍历,减少缩进层级,代码更简洁 - 用集合成员判断
in替代长串的==和||判断,后续需要新增/删除匹配值时直接修改集合即可,维护成本更低 - 用OPL原生的蕴含运算符
=>替代if-else分支结构,符合OPL声明式约束的语法习惯,运行效率也更高 - 如果偏好保留if-else写法,也可以简化为以下形式:
forall(j in J, i in I1) { if (macc[i][j] in fixedMSet) y[i][j][macc[i][j]] == 1; else if (macc[i][j] == 3) y[i][j][3] == 1 || y[i][j][4] == 1; }
内容的提问来源于stack exchange,提问作者Francesca
相关产品推荐
相关产品推荐

