在回调(CPXcutcallbackadd)中添加用户剪切后,如何编写问题公式(CPXwriteprob)
How to write problem formulation (CPXwriteprob) after user cut is added in callback (CPXcutcallbackadd)?
我正试图在cplex回调函数中添加用户剪切。为了检查这些剪切,我在添加剪切后编写了一个lp文件。但是,lp文件中没有显示用户剪切。
根据这个论坛帖子(网址:http://www.ibm.com/developerworks/community/forums/html/topic?id=82b92bee-4ac7-41dd-b1fc-606eae3514f3),剪切应该以"u"开头。
我的代码的相关部分(基于示例文件bendersatsp.c):
int CPXPUBLIC benders_solver::benders_callback(CPXCENVptr env, void *cbdata, int wherefrom, void *cbhandle, int *useraction_p)
{
int status = 0;
int do_separate = 0;
USER_CBHANDLE *user_cbhandle = (USER_CBHANDLE *)cbhandle;
int purgeable;
*useraction_p = CPX_CALLBACK_DEFAULT;
/* Decide if we want to separate cuts, depending on the parameter wherefrom */
switch (wherefrom) {
case CPX_CALLBACK_MIP_CUT_FEAS: // 115
do_separate = 1;
break;
case CPX_CALLBACK_MIP_CUT_LAST: // 114: indicates that CPLEX is done adding cuts and the user has a last chance to add cuts
do_separate = 1;
break;
case CPX_CALLBACK_MIP_CUT_LOOP: // 106: The callback was called from the cut loop CPLEX executes at each node.
do_separate = 0;
break;
default:
fprintf(stderr, "Unexpected value of wherefrom: %dn", wherefrom);
do_separate = 0;
}
if (!do_separate) goto TERMINATE;
/* Get the current x solution */
status = CPXgetcallbacknodex(env, cbdata, wherefrom, user_cbhandle->x, 0, user_cbhandle->num_x_cols - 1);
if (status) {
fprintf(stderr, "Error in CPXgetcallbacknodex: status = %dn", status);
goto TERMINATE;
}
CPXCLPptr lp_p;
status = CPXgetcallbacklp(env, cbdata, wherefrom, &lp_p); // store master problem to lp_p
changeSub_d(user_cbhandle, user_cbhandle->subenv, user_cbhandle->subproblem_d);
/* Solve the worker LP and look for a violated cut */
CPXsetintparam(user_cbhandle->subenv, CPX_PARAM_PREIND, 0);
int optstatus = CPXlpopt(user_cbhandle->subenv, user_cbhandle->subproblem_d);
worker_lp_sol_stat = CPXgetstat(user_cbhandle->subenv, user_cbhandle->subproblem_d);
/* Make cut */
int matind[21000] = { 0 };
double matval[21000] = { 0 };
double rhs[1];
char sense[1];
int nbnz{ 0 };
status = addBendersCut(user_cbhandle, worker_lp_sol_stat, env, lp_p, cbdata, wherefrom);
int purgeable = CPX_USECUT_FORCE;
status = CPXcutcallbackadd(env, cbdata, wherefrom, nbnz, rhs[0], sense[0], matind, matval, purgeable);
status = CPXwriteprob(masterenv, masterproblem, "cback.lp", "LP");
/* Tell CPLEX that cuts have been created */
if (status)
goto TERMINATE;
*useraction_p = CPX_CALLBACK_SET;
TERMINATE:
/* If an error has been encountered, we fail */
if (status) *useraction_p = CPX_CALLBACK_FAIL;
return status;
} /* END benders_callback */
bool benders_solver::startSolve()
{
loadGeneralData(sol);
// Initialize the CPLEX environment
masterenv = CPXopenCPLEX(&status);
subenv = CPXopenCPLEX(&status);
loadMasterProblem();
loadSubProblem();
USER_CBHANDLE user_cbhandle;
int separate_fractional_solutions = 1;
/* Init the cut callback data structure */
status = init_user_cbhandle(&user_cbhandle, separate_fractional_solutions);
/* Let MIP callbacks work on the original model */
status = CPXsetintparam(env, CPXPARAM_MIP_Strategy_CallbackReducedLP, CPX_OFF);
status = CPXsetintparam(env, CPX_PARAM_PRELINEAR, 0);
status = CPXsetintparam(env, CPX_PARAM_MIPCBREDLP, 0);
status = CPXsetintparam(env, CPXPARAM_Threads, 1);
/* Turn on traditional search for use with control callbacks */
status = CPXsetintparam(env, CPXPARAM_MIP_Strategy_Search, CPX_MIPSEARCH_TRADITIONAL);
if (user_cbhandle->separate_fractional_solutions) {
status = CPXsetusercutcallbackfunc(env, benders_callback, user_cbhandle);
}
/* Optimize the problem and obtain solution status */
status = CPXsetintparam(masterenv, CPX_PARAM_PREIND, 0);
status = CPXsetdblparam(masterenv, CPX_PARAM_TILIM, 300);
status = CPXsetstrparam(masterenv, CPXPARAM_WorkDir, "c:/cplex/");
status = CPXsetintparam(masterenv, CPXPARAM_MIP_Strategy_File, 2);
status = CPXsetdblparam(masterenv, CPXPARAM_WorkMem, 6000);
status = CPXsetintparam(masterenv, CPX_PARAM_MEMORYEMPHASIS, 1);
status = CPXmipopt(masterenv, masterproblem);
status = CPXsetlogfile(masterenv, NULL);
return true;
}
当您编写LP时,它看起来像是在使用原始模型对象(即masterproblem
):
status = CPXwriteprob(masterenv, masterproblem, "cback.lp", "LP");
相反,您需要使用节点LP,如下所示:
CPXLPptr _lp;
status = CPXgetcallbacknodelp(env, cbdata, wherefrom, &_lp);
CPXwriteprob(env, _lp, "cback.lp", "LP");
正如你链接到的论坛帖子中提到的:
CPXcutcallbackadd()函数不使用参数来提供名称。在cback.lp文件中,您添加的剪切的名称将以带"u",后跟一个数字。所以你可以找到哪些行是剪切是你添加的,但你无法轻松地将它们映射回事物在您的代码中
另一个值得一提的要点(为了澄清我在评论中提到的内容)是,在回调之外,当使用CPXwriteprob
时,您的剪切将不会显示(即,在回调中的树搜索过程中动态添加的任何剪切都不会导出)。但是,如果在优化之前使用CPXaddusercuts添加用户剪切,则它们会。
另一个与您类似的问题可以在developerWorks论坛上找到。
相关文章:
- 编写时C++中的输入重定向问题
- 最大的回文产品 - 程序未运行,编写解决方案但无法理解问题
- 标准对此指向成员函数类型模板参数有何说明?是我的代码有误,还是 MSVS 16.6 有问题?
- 编写 cin.get() 以接收字符数组时出现问题
- 执行用 C++ 编写的.exe(使用 mingw 编译器)时出现问题
- 我正在编写一个代码来将 int 数组存储在文件中,然后用 c++ 检索它,但是检索第一项是假值,我该如何解决这个问题?
- 编写完整专业化以识别void类型的问题
- 我在编写从文本文件中读取数据并按升序打印的代码时遇到问题
- FSTREAM的问题读取确定,但不编写用户输入字符串
- 在 MacOS Sierra 上编译用 C++ 编写的开源软件时出现问题
- UTF-16LE 编码问题与 Qt 文本编辑器用 C++ 编写
- 在C++为矢量编写自定义虚拟分配器时遇到问题
- 在回调(CPXcutcallbackadd)中添加用户剪切后,如何编写问题公式(CPXwriteprob)
- 字符 * 和字符串在C++中有何不同?(在描述中编写代码)
- 为gzipped流编写自定义streambuf的问题
- 编写 JSON 解释器时出现设计问题
- 我必须编写一段代码,基本上执行c++中的strlen()函数,哪里出了问题
- 用std::vector编写可调整大小的矢量时出现问题
- 在微控制器上编写 UART 控制台时出现 UTF-8 问题
- 在编写堆栈实现 c++ 时遇到问题