OPL CPLEX主块循环中动态添加元组数据行的技术求助
问题修复方案
核心问题定位
- Links行添加错误:你用
data.Links.add(iter)试图添加整数,但Links是tuple link类型集合,不是整数集合,无法直接添加整数索引。 - 输出数组初始化越界:原代码中
output数组的初始化范围和M(1..5)不匹配,会导致后续赋值时索引越界。 - 变量固定逻辑不完整:仅固定值为1的
x变量,未覆盖所有需要保持恒定的变量。
修正后的完整代码
{int}s={}; range M = 1..5; tuple link { key int N; int fromnode; int tonode; int EP; int LD; float I; int dr; }; {link} Links = ...; main{ var source = new IloOplModelSource("subset.mod"); var cplex = new IloCplex(); var def = new IloOplModelDefinition(source); // 修正输出数组初始化,适配M和N的实际范围 var output = new Array(thisOplModel.M.size + 1); for (var i=1; i<=thisOplModel.M.size; i++) { output[i] = new Array(8); // N最大为7,索引预留到7 for(var j=1; j<=7; j++) { output[i][j] = 0.0; } } for(var iter=1; iter<=7; iter++) { var opl = new IloOplModel(def, cplex); var data = new IloOplDataElements(); data.M = thisOplModel.M; // 创建空的tuple link集合,替代原空整数集合 data.Links = new IloOplCollection(thisOplModel.Links.getType()); // 从原Links集合中取出第iter个元组(数组索引从0开始) var currentLink = thisOplModel.Links.toArray()[iter-1]; data.Links.add(currentLink); opl.addDataSource(data); opl.generate(); // 固定上一次迭代的所有x变量值 if (iter != 1) { for (var k in data.M) { for (var r in data.N) { var val = output[k][r]; opl.x[k][r].LB = val; opl.x[k][r].UB = val; writeln("固定x[",k,"][",r,"] = ", val); } } } if (cplex.solve()) { writeln('\n================================='); writeln("ITERATION ", iter, " / TIME = ", cplex.getCplexTime()); writeln("当前添加的Link: ", currentLink); writeln('\n****OBJ************'); writeln("OBJ = " + cplex.getObjValue()); } else { writeln("No solution"); } opl.postProcess(); // 保存当前迭代的x变量解 for (var k in data.M) { for (var r in data.N) { output[k][r] = opl.x[k][r].solutionValue; } } data.end(); opl.end(); } }
关键修正点说明
- 正确添加Links行:通过
Links.toArray()将原集合转为数组,按迭代次数取对应元组,确保每次迭代添加一行正确的tuple数据。 - 完整固定变量值:从第二次迭代开始,将所有
x变量的上下界设置为上一次迭代的解,强制后续迭代中x的值完全恒定。 - 避免数组越界:根据
M和N的实际范围初始化output数组,解决索引越界问题。
内容的提问来源于stack exchange,提问作者yalan
相关产品推荐
相关产品推荐

