为什么当 cplex presolve 开启时 MIP 不可行?
Why is MIP infeasible when cplex presolve is ON?
我在 C++ 程序中使用 cplex 可调用库(版本 12.6.3)来求解混合整数程序。代码的相关部分如下所示:
loadSubProblem();
double TimeLimit = 999999;
double MipGap = 0.00;
double NbMipSol = 999999;
//status = CPXsetintparam(subenv, CPX_PARAM_PREIND, CPX_OFF); // set presolve on/off
status = CPXsetdblparam(subenv, CPX_PARAM_TILIM, TimeLimit); // time limit of ... (s)
status = CPXsetintparam(subenv, CPX_PARAM_INTSOLLIM, 1); // stop after 1 solution
status = CPXsetintparam(subenv, CPXPARAM_MIP_Strategy_File, 3); // 0 No node file // 1 Node file in memory and compressed; default // 2 Node file on disk // 3 Node file on disk and compressed (see: https://www.ibm.com/support/knowledgecenter/de/SSSA5P_12.7.0/ilog.odms.cplex.help/CPLEX/Parameters/topics/NodeFileInd.html)
FILE * fp;
fp = CPXfopen("logfile_sub.log", "w");
status = CPXsetlogfile(subenv, fp);
status = CPXmipopt(subenv, subproblem);
status = CPXgetstat(subenv, subproblem);
// close log file
status = CPXsetlogfile(subenv, NULL);
int cur_numcols = CPXgetnumcols(subenv, subproblem);
// Obtain solution
double objval;
double best_bound;
solstat = 0; // reset solstat
status = CPXgetbestobjval(subenv, subproblem, &best_bound);
status = CPXsolution(subenv, subproblem, &solstat, &objval, primalsolution_subproblem, NULL, NULL, NULL);
第一行正确地构建了子问题,正如我可以从 lp 文件中检查的那样。 CPXmipopt 的状态为 0。但是,根据日志文件,求解器似乎过早停止并且未找到整数解。 CPXgetstat returns 状态 103 ("integer infeasible")。因此,错误发生在最后一行,状态为 1217 ("no solution exists")。 Solstat 仍然是 0.
但是,当预求解器关闭时(第7行),似乎没有问题。 CPXmipopt 以状态 0 结束,日志文件显示已找到整数解并且可以使用 CPXsolution 获得解(solstat 为 104,如预期的那样)。
我的问题是:什么原因可能导致这种行为?为什么开启预处理器会导致找不到解决方案,如何解决?
根据有用的评论,我发现我的问题确实是病态的。公差的差异(如评论和 tech note 中所述)导致问题在预求解关闭时变为 "feasible"。
我的问题重写后,不管presolve打开还是关闭都不行。
我在 C++ 程序中使用 cplex 可调用库(版本 12.6.3)来求解混合整数程序。代码的相关部分如下所示:
loadSubProblem();
double TimeLimit = 999999;
double MipGap = 0.00;
double NbMipSol = 999999;
//status = CPXsetintparam(subenv, CPX_PARAM_PREIND, CPX_OFF); // set presolve on/off
status = CPXsetdblparam(subenv, CPX_PARAM_TILIM, TimeLimit); // time limit of ... (s)
status = CPXsetintparam(subenv, CPX_PARAM_INTSOLLIM, 1); // stop after 1 solution
status = CPXsetintparam(subenv, CPXPARAM_MIP_Strategy_File, 3); // 0 No node file // 1 Node file in memory and compressed; default // 2 Node file on disk // 3 Node file on disk and compressed (see: https://www.ibm.com/support/knowledgecenter/de/SSSA5P_12.7.0/ilog.odms.cplex.help/CPLEX/Parameters/topics/NodeFileInd.html)
FILE * fp;
fp = CPXfopen("logfile_sub.log", "w");
status = CPXsetlogfile(subenv, fp);
status = CPXmipopt(subenv, subproblem);
status = CPXgetstat(subenv, subproblem);
// close log file
status = CPXsetlogfile(subenv, NULL);
int cur_numcols = CPXgetnumcols(subenv, subproblem);
// Obtain solution
double objval;
double best_bound;
solstat = 0; // reset solstat
status = CPXgetbestobjval(subenv, subproblem, &best_bound);
status = CPXsolution(subenv, subproblem, &solstat, &objval, primalsolution_subproblem, NULL, NULL, NULL);
第一行正确地构建了子问题,正如我可以从 lp 文件中检查的那样。 CPXmipopt 的状态为 0。但是,根据日志文件,求解器似乎过早停止并且未找到整数解。 CPXgetstat returns 状态 103 ("integer infeasible")。因此,错误发生在最后一行,状态为 1217 ("no solution exists")。 Solstat 仍然是 0.
但是,当预求解器关闭时(第7行),似乎没有问题。 CPXmipopt 以状态 0 结束,日志文件显示已找到整数解并且可以使用 CPXsolution 获得解(solstat 为 104,如预期的那样)。
我的问题是:什么原因可能导致这种行为?为什么开启预处理器会导致找不到解决方案,如何解决?
根据有用的评论,我发现我的问题确实是病态的。公差的差异(如评论和 tech note 中所述)导致问题在预求解关闭时变为 "feasible"。
我的问题重写后,不管presolve打开还是关闭都不行。