IBM ILOG CPLEX求解MIP:迭代输出未留存的问题修改咨询
问题:CPLEX迭代中无法留存前一次结果的修改方案
使用IBM ILOG CPLEX Optimization Studio求解混合整数规划(MIP)问题,所有参数均已定义。需求是将第一次迭代的输出结果作为下一次迭代的输入,同时修改部分数据,但当前代码中第一次迭代结果未留存到后续迭代,导致后续迭代OBJ始终为0,需修改代码中的关键逻辑。
主代码块(原代码)
{string}s={"aa","bb","cc","dd","ee"}; main{ var source = new IloOplModelSource("subset.mod"); var cplex = new IloCplex(); var def = new IloOplModelDefinition(source); var output=0; for(var iter=1;iter<=5;iter++) { var m=Opl.item(thisOplModel.s,iter-1); thisOplModel.M.add(m); var opl = new IloOplModel(def,cplex); var data= new IloOplDataElements(); data.M=thisOplModel.M; data.N=thisOplModel.N; opl.addDataSource(data); opl.generate(); if (iter!=1){ for (var k in data.M){ for (var r in data.N){ opl.x[k][r].LB=output; opl.x[k][r].UB=output;}}} if (cplex.solve()) { writeln("OBJ = " + cplex.getObjValue()); } else { writeln("No solution"); } opl.postProcess(); for (var r in data.N){ for (var k in data.M){ if (output==1){ output=opl.x[k][r].solutionValue; } } data.end(); opl.end(); } }
运行结果
====================================== ITERATION 1 M= {"aa"} OBJ = 4.1 x[aa][b] = 1 x[aa][c] = 1 ====================================== ITERATION 2 M= {"aa" "bb"} OBJ = 0 ====================================== ITERATION 3 M= {"aa" "bb" "cc"} OBJ = 0 ====================================== ITERATION 4 M= {"aa" "bb" "cc" "dd"} OBJ = 0 ====================================== ITERATION 5 M= {"aa" "bb" "cc" "dd" "ee"} OBJ = 0
问题根源与修改方案
核心问题
- 结果保存逻辑错误:初始
output=0,仅当output==1时才会赋值,但第一次迭代后output仍为0,后续根本不会进入赋值分支,导致output始终为0,后续迭代强制所有x[k][r]的上下界为0,求解结果自然为0。 - 结果存储方式错误:用单个变量
output无法保存多个x[k][r]的解,只能覆盖为最后一个值,无法完整传递所有前次迭代的结果。 - 循环顺序与赋值逻辑矛盾:遍历
r再遍历k的顺序会导致output被多次覆盖,且未处理新增元素(如bb、cc)的变量存在性问题。
修改后的代码
{string}s={"aa","bb","cc","dd","ee"}; main{ var source = new IloOplModelSource("subset.mod"); var cplex = new IloCplex(); var def = new IloOplModelDefinition(source); // 改用二维字典保存所有变量的前次解 var lastSolution = new IloMap(); for(var iter=1;iter<=5;iter++) { var m=Opl.item(thisOplModel.s,iter-1); thisOplModel.M.add(m); var opl = new IloOplModel(def,cplex); var data= new IloOplDataElements(); data.M=thisOplModel.M; data.N=thisOplModel.N; opl.addDataSource(data); opl.generate(); if (iter!=1){ // 遍历前次解,为对应变量设置固定上下界 for (var k in lastSolution.keys()){ var rMap = lastSolution.get(k); for (var r in rMap.keys()){ // 确保当前模型中存在该变量,避免新增元素导致的错误 if (opl.x.hasKey(k) && opl.x[k].hasKey(r)){ opl.x[k][r].LB = rMap.get(r); opl.x[k][r].UB = rMap.get(r); } } } } if (cplex.solve()) { writeln("OBJ = " + cplex.getObjValue()); // 清空并保存当前迭代的所有解 lastSolution.clear(); for (var k in data.M){ var rMap = new IloMap(); lastSolution.put(k, rMap); for (var r in data.N){ if (opl.x[k][r].solutionValue != undefined){ rMap.put(r, opl.x[k][r].solutionValue); writeln("x["+k+"]["+r+"] = " + opl.x[k][r].solutionValue); } } } } else { writeln("No solution"); } opl.postProcess(); data.end(); opl.end(); } }
关键修改点说明
- 替换单个
output变量为lastSolution二维字典,完整保存所有x[k][r]的解,避免值覆盖。 - 移除错误的
if (output==1)判断,确保第一次迭代求解成功后直接保存结果。 - 后续迭代时,遍历
lastSolution为已有变量设置固定上下界,同时增加变量存在性判断,适配每次新增的元素(如bb、cc等)。 - 调整解的保存顺序,先遍历
k再遍历r,确保所有变量的解都被正确存储。
内容的提问来源于stack exchange,提问作者yalan
相关产品推荐
相关产品推荐

