Digging deeper, I notice the following.
Even though the cut, let us say 2x1 + 3x2 <= 4 is identified as violated given current xbar in a user cut callback and it is added via CPXcutcallbackadd with argument CPX_USECUT_FORCE, CPLEX identifies this cut using prefix q:
Original Message:
Sent: Sat August 03, 2024 12:22 PM
From: CPLEX User
Subject: Query on admipex1.c example and CPLEX documentation regarding callbacks
I have a follow up query on the behavior of CPXgetcallbacklp and CPXgetcallbacknodelp in different callback functions at the root node which I hope the developers can address. I have an MIP where at the root node, my user cuts are being added via a user writtencut callback. I add these cuts via CPXcutcallbackadd with argument CPX_USECUT_FORCE. This, I hope will ensure that this added cut is never removed by CPLEX anywhere in the tree. i.e., it will remain a globally valid cut.
However, in a subsequent cut callback still at the root node, I notice that I obtain an xbar solution via CPXgetcallbacknodex at the root node that violates the constraint above.
(1) Is this behavior expected? Why is the xbar violating the cut even when the cut was added with argument CPX_USECUT_FORCE ?
(2) I notice that the lp that I obtain via CPXgetcallbacknodelp() and CPXgetcallbacklp() in the solve callback are different from the ones I obtain via the same functions in the cut callback both of the same root node. Is there any reason for this?
Thanks.
------------------------------
CPLEX User
Original Message:
Sent: Sun July 21, 2024 04:48 AM
From: CPLEX User
Subject: Query on admipex1.c example and CPLEX documentation regarding callbacks
Edited to add: sorry, did not realize the difference between CPXgetcallbacknodelp and CPXgetcallbacklp. Below question therefore is invalid as of now. I will study the example admipex1.c and documentation further and more carefully to see if there is still something I do not understand.
----
admipex1.c is the suggested example to understand branch callback. I have the following query regarding it:
According to https://www.ibm.com/docs/en/icos/22.1.1?topic=lcp-mip-callback-switch-between-original-model-reduced-presolved-model
"The routine CPXgetcallbacknodelp is an exception: it always accesses the current node LP associated with the presolved model, regardless of the setting of this parameter.", the parameter in question being CPXPARAM_MIP_Strategy_CallbackReducedLP
Now, admipex1.c sets this paramter to CPX_OFF in line 171. We also have on line 398 of admipex1.c, the following in the user written branch callback:
status = CPXgetcallbacklp (env, cbdata, wherefrom, &lp);
followed by
cols = CPXgetnumcols (env, lp); //Suppose the number of variables in the presolved version is 10
and
x = (double *) malloc (cols * sizeof (double)); //So, x is allocated space for 10 doubles.
Thus, I understand that lp points to the presolved problem at the current node.
From https://www.ibm.com/docs/en/cofz/12.10.0?topic=g-cpxxgetcallbacknodex-cpxgetcallbacknodex, we have:
"The routine CPXXgetcallbacknodex/CPXgetcallbacknodex retrieves the primal variable (x) values for the subproblem at the current node during MIP optimization from within a user-written callback. The values are from the original problem if the MIP callback switch between original model and reduced, presolved model (CPXPARAM_MIP_Strategy_CallbackReducedLP) is set to CPX_OFF; otherwise, they are from the presolved problem."
We have the following line (line # 424) in the branch callback function in admipex1.c
status = CPXgetcallbacknodex (env, cbdata, wherefrom, x, 0, cols-1);
The question here is about the integrity/correctness of x. Since CPXPARAM_MIP_Strategy_CallbackReducedLP has been set to CPX_OFF, wouldn't the functioin above return the primal variable values from the original problem and not the presolved problem? So, if the original problem had 15 variables which presolve has reduced to 10, isn't there incompatibility?
Thank you.
------------------------------
CPLEX User
------------------------------