OPL迭代解保存异常求助:结果未保留且参数更新无效
问题分析与修复方案
核心问题点
- 单变量存储解值导致覆盖:使用单个
output变量保存所有x[k][r.N]的解,每次循环都会被最后一个r的结果覆盖,后续迭代无法绑定所有前序变量的正确值。 - 未保留历史迭代约束:每次迭代新建
opl模型时,仅对当前k的x变量设置上下界,没有固定之前所有迭代中已求解出的x变量值,导致迭代4、5丢失前序结果。 - M集合更新逻辑不严谨:
data2.M=thisOplModel.s; data2.M.add(k);的写法会每次从原始s集合初始化再添加k,容易导致M集合未按预期逐步扩展。 - 模型对象过早销毁:每次迭代结束调用
opl.end()销毁模型,导致之前的变量和约束无法传递到下一次迭代。
修复后的代码
main { var source = new IloOplModelSource("subset.mod"); var cplex = new IloCplex(); var def = new IloOplModelDefinition(source); // 用字典存储所有历史解值,键为"k_rN"格式字符串 var savedSolutions = new IloMap(); // 初始化M集合,从原始s开始逐步扩展 var currentM = new IloIntSet(); for(var m in thisOplModel.s) { currentM.add(m); } for(var k=1;k<=5;k++) { currentM.add(k); var opl = new IloOplModel(def,cplex); var data2= new IloOplDataElements(); data2.M = currentM; data2.N=thisOplModel.N; data2.Links=thisOplModel.Links; data2.CAP=thisOplModel.CAP; data2.Tr=thisOplModel.Tr; opl.addDataSource(data2); opl.generate(); // 绑定所有历史迭代的变量值 if (!savedSolutions.isEmpty()) { for(var key in savedSolutions.keys()) { var parts = key.split("_"); var iter = parseInt(parts[0]); var nVal = parts[1]; opl.x[iter][nVal].LB = savedSolutions.get(key); opl.x[iter][nVal].UB = savedSolutions.get(key); } } if (cplex.solve()) { writeln("ITERATION ", k); writeln('\n****OBJ************'); writeln("OBJ = " + cplex.getObjValue()); writeln('\n****x************'); // 保存当前迭代的所有x变量解 for (var r in data2.Links){ var solVal = opl.x[k][r.N].solutionValue; writeln("x["+k+"]["+r.N+"] = " + solVal); savedSolutions.put(k + "_" + r.N, solVal); } } else { writeln("No solution"); } opl.postProcess(); data2.end(); opl.end(); } savedSolutions.end(); }
关键修改说明
- 字典存储历史解:创建
IloMap类型的savedSolutions,以"k_rN"(如"1_b")为键存储每个x[k][r.N]的解值,避免单变量覆盖问题。 - 正确扩展M集合:提前初始化
currentM,每次迭代添加当前k,确保M集合按{1}→{1,2}→{1,2,3}...的顺序逐步扩展。 - 绑定所有历史变量约束:每次迭代生成模型后,遍历
savedSolutions中的所有历史解,将对应的x变量上下界固定为历史值,确保前序迭代结果被保留。 - 完整保存当前迭代解:求解成功后,遍历当前迭代的所有
x[k][r.N]变量,将解值存入字典,同时打印输出便于验证。
内容的提问来源于stack exchange,提问作者yalan
相关产品推荐
相关产品推荐

