Decision Optimization

 View Only
  • 1.  Query on admipex1.c example and CPLEX documentation regarding callbacks

    Posted Sun July 21, 2024 04:49 AM
    Edited by CPLEX User Sun July 21, 2024 04:52 AM

    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
    ------------------------------



  • 2.  RE: Query on admipex1.c example and CPLEX documentation regarding callbacks

    Posted Sat August 03, 2024 12:23 PM

    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
    ------------------------------



  • 3.  RE: Query on admipex1.c example and CPLEX documentation regarding callbacks

    Posted Sun August 04, 2024 12:06 AM

    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:

    q5: 2x1 + 3x2 <= 4

    I am able to observe this via reading the LP pointer file returned by CPXgetcallbacklp in the solve callback immediately following the user cut callback.

    So, for some reason, instead of being identified as a user generated cut, therefore identifying that cut via prefix u (as indicated in this thread https://community.ibm.com/community/user/ai-datascience/discussion/naming-user-cuts-added-in-a-callback#bm657c0828-c00c-4946-80c1-ad556171255c)

    CPLEX deems this to be some cplex generated (?) cut and hence feels free to remove it at a later stage.

    How should I proceed now?

    Thanks.



    ------------------------------
    CPLEX User
    ------------------------------