IBM ILOG CPLEX多场景自动化测试结果导出异常解决方案咨询
问题:CPLEX多场景测试中IloNumExp/IloNumVar写入Excel异常
我在使用CPLEX进行多场景自动化测试时遇到问题。需要测试多组目标函数加权权重与ratio参数的场景,比如初始设置W1=0.2、W2=0.7、W3=0.1,ratio[1]=0、ratio[2]=0,随后仅将ratio[3]从0.1递增至0.7。但将IloNumExp和IloNumVar类型的变量结果写入Excel时出现异常。
变量与参数说明
变量说明
- COUTTOTAL:项目总成本
- Cmax:项目完成时间
- QTEREMP:复用数量,需最大化该变量
参数说明
- W1、W2、W3:用户指定的权重
- S1、S2、S3:确保变量重要性一致的修正因子
- esti*:单变量极值(最大化/最小化时的最值)
注:已尝试用Gemini实现自动化部分,该部分可调整。
相关代码
minimize W1 *S1*((TOTALCOST-estiMinCost)/(estiMaxCost-estiMinCost)) + W2*S2*((Cmax-estiMinTime)/(estiMaxTime-estiMinTime)) - W3*S3*((QTEREMP-estiMinQTEM)/(estiMaxQTEM-estiMinQTEM)); //Constrait.... subject to { ... } main { var ofile = new IloOplOutputFile("resultats_scenarios_ratio2_varie.csv"); ofile.writeln("W1;W2;W3;ratio[1];ratio[2];ratio[3];Objectif;COUTTOTAL;Cmax;QTEREMP"); var r2_start = 0.0; var r2_end = 0.2; var r2_step = 0.1; for (var r2_val = r2_start; r2_val <= r2_end + 0.0001; r2_val += r2_step) { for (var w_index = 1; w_index <= 3; w_index++) { var currentW = thisOplModel.W_combinaisons[w_index]; W1 = currentW[1]; W2 = currentW[2]; W3 = currentW[3]; for (var r3 = 0.0; r3 <= 0.7 + 0.0001; r3 += 0.1) { var tempRatio = new Array(4); // Taille 4 pour supporter les index 1, 2, 3 tempRatio[1] = 0.0; tempRatio[2] = r2_val; tempRatio[3] = r3; writeln("--- Résolution : R2=", ratio_script[2], ", W=(", W1, ", ", W2, ", ", W3, ") et R3=", ratio_script[3], " ---"); if (cplex.solve()) { ofile.writeln(W1, ";", W2, ";", W3, ";", //CORRECTION : Utiliser ratio_script au lieu de ratio ratio_script[1], ";", ratio_script[2], ";",ratio_script[3], ";",cplex.getObjValue(), ";", thisOplModel.TestCOU, ";", thisOplModel.Cmax, ";", thisOplModel.QTEREMP); } else { ofile.writeln(W1, ";", W2, ";", W3, ";", ratio_script[1], ";", ratio_script[2], ";", ratio_script[3], ";", "No Solution", ";", "N/A", ";", "N/A", ";", "N/A"); } } } } }
解决方案
1. 修正变量取值方式
直接输出IloNumVar/IloNumExp对象会返回其定义信息而非求解值,需调用.value方法获取实际数值:
thisOplModel.TestCOU.value; thisOplModel.Cmax.value; thisOplModel.QTEREMP.value
2. 正确传递ratio参数
代码中创建了tempRatio数组,但未赋值给模型中的ratio_script变量,导致求解时使用初始值而非循环设置的参数。需添加赋值语句:
thisOplModel.ratio_script = tempRatio;
3. 修正调试信息
调试输出中使用未赋值的ratio_script变量,应改为直接输出循环变量r2_val和r3,确保信息准确:
writeln("--- Résolution : R2=", r2_val, ", W=(", W1, ", ", W2, ", ", W3, ") et R3=", r3, " ---");
4. 优化文件写入与精度控制
- 对输出数值格式化,避免冗余信息,例如保留2位小数:
cplex.getObjValue().toFixed(2) - 循环结束后调用
ofile.close(),确保内容写入磁盘
修正后的核心代码片段
main { var ofile = new IloOplOutputFile("resultats_scenarios_ratio2_varie.csv"); ofile.writeln("W1;W2;W3;ratio[1];ratio[2];ratio[3];Objectif;COUTTOTAL;Cmax;QTEREMP"); var r2_start = 0.0; var r2_end = 0.2; var r2_step = 0.1; for (var r2_val = r2_start; r2_val <= r2_end + 0.0001; r2_val += r2_step) { for (var w_index = 1; w_index <= 3; w_index++) { var currentW = thisOplModel.W_combinaisons[w_index]; thisOplModel.W1 = currentW[1]; thisOplModel.W2 = currentW[2]; thisOplModel.W3 = currentW[3]; for (var r3 = 0.0; r3 <= 0.7 + 0.0001; r3 += 0.1) { var tempRatio = new Array(4); tempRatio[1] = 0.0; tempRatio[2] = r2_val; tempRatio[3] = r3; thisOplModel.ratio_script = tempRatio; writeln("--- Résolution : R2=", r2_val, ", W=(", W1, ", ", W2, ", ", W3, ") et R3=", r3, " ---"); if (cplex.solve()) { var objVal = cplex.getObjValue().toFixed(2); var coutTotal = thisOplModel.TestCOU.value.toFixed(2); var cmaxVal = thisOplModel.Cmax.value.toFixed(2); var qterempVal = thisOplModel.QTEREMP.value.toFixed(2); ofile.writeln(W1, ";", W2, ";", W3, ";", tempRatio[1], ";", tempRatio[2], ";", tempRatio[3], ";", objVal, ";", coutTotal, ";", cmaxVal, ";", qterempVal); } else { ofile.writeln(W1, ";", W2, ";", W3, ";", tempRatio[1], ";", tempRatio[2], ";", tempRatio[3], ";", "No Solution", ";", "N/A", ";", "N/A", ";", "N/A"); } } } } ofile.close(); }
内容的提问来源于stack exchange,提问作者Félix Veillette
相关产品推荐
相关产品推荐

