CPLEX OPL迭代优化中如何正确更新并打印矩阵pa?
CPLEX OPL主函数迭代优化中矩阵更新与打印的脚本错误修复
原代码核心问题
opl变量在for循环内部定义,循环外调用opl.end()会触发未定义错误- 错误直接修改模型内的
opl.pa,实际pa是主脚本声明的数组,应操作主脚本的pa变量 - 模型中的决策变量(
sreq、vpile、cslot)是变量对象,需通过.solutionValue获取优化后的数值,不能直接作为数值使用 - 缺少打印pa矩阵的逻辑
修正后的代码
int Nod=41; range NodRange = 1..Nod; int nr=140; range RRange = 1..nr; int TSlot = 96; range TRange = 1..TSlot; int ncs=6; range csrange=1..ncs; int piles=12; range np=1..piles; int nv=3; range nvrange=1..nv; main { var source = new IloOplModelSource("subvalue.mod"); var cplex = new IloCplex; var def = new IloOplModelDefinition(source); // 初始化主脚本中的pa矩阵,默认值为0 var pa= new int [np][TRange]; for(var v=1;v<=3;v++) { var opl = new IloOplModel(def, cplex); var data = new IloOplDataSource("MultipleEtoCS.dat"); var data2=new IloOplDataElements(); data2.cev=v; opl.addDataSource(data2); opl.addDataSource(data); opl.generate(); if (!cplex.solve()) { writeln("No solution exists for v = ", v); opl.end(); continue; }else{ opl.postProcess(); writeln("Solution for v = ", v, " is = ", cplex.getObjValue()); // 获取决策变量的实际优化值 var sreqVal = opl.sreq[v].solutionValue; var vpileVal = opl.vpile[v].solutionValue; var cslotVal = opl.cslot[v].solutionValue; // 更新主脚本中的pa矩阵 for (var j in opl.csrange){ if(j <= sreqVal) { var tIndex = cslotVal + 1 + j; // 避免时间槽索引越界 if(tIndex >= TRange.first && tIndex <= TRange.last) { pa[vpileVal][tIndex] = 1; } else { writeln("Warning: Time slot index ", tIndex, " out of range for v = ", v); } } } } opl.end(); // 每次迭代后释放模型实例,避免内存泄漏 } // 打印最终的pa矩阵 writeln("\nFinal pa matrix:"); for(var p in np) { writeln("Pile ", p, ": ", pa[p]); } }
关键修改说明
- 作用域修正:将
opl.end()移至for循环内部,确保每次迭代后释放当前模型实例,避免循环外调用未定义变量 - 决策变量取值:通过
.solutionValue方法获取优化后决策变量的实际数值,而非直接使用变量对象 - 矩阵操作修正:直接修改主脚本中声明的
pa数组,而非模型内的变量 - 越界检查:增加时间槽索引合法性判断,避免数组越界错误
- 打印逻辑补充:循环结束后遍历pa矩阵,输出所有堆的时间槽数据
内容的提问来源于stack exchange,提问作者SUBHADARSHINI PANDA
相关产品推荐
相关产品推荐

