JuMP 0.18 + CPLEX: How to force user cuts?

Dear community,

is there any way to force CPLEX to add all user cuts (i.e., passing the option CPX_USECUT_FORCE)?

Here https://github.com/JuliaOpt/CPLEX.jl/blob/master/src/cpx_callbacks.jl the option seems to be hard-coded to CPX_USECUT_PURGE, but I want to avoid changing the parameter in the source code of the package.

Thank you in advance!!


UPDATE:
I now changed the parameters manually in the source to CPX_USECUT_FORCE at line 62/65 in the cpx_callbacks.jl but this did not solve my problem:
I have an ILP model in which I use lazy and user callbacks and I want to add user cuts as long as I find some before branching starts. In particular I am interested in the root relaxation. In an minimal instance there are 3 user cuts. However, the user callback is only called once and therefore the last two cuts are not added.

I suggest manually modifying the source until you get something that works.

Note that CPX_USECUT_FORCE will only guarantee that if a cut is added, it will not be purged later on in the solve. It doesn’t guarantee that the callback will be called in the first place.

I don’t think you can control when and how many times CPLEX decides to call your callback.

Thank you for the reply. I now had a closer look, and it seems that even the first user cut is not added. At least I know from the C++ interface that the LP relaxation is resolved if a new user cut is added, which does not happen in my case. I.e, Since I stop the algorithm right after the root node, I obtain the same results with only lazy cuts and with both, lazy and user cuts. However, adding the user cuts manually (hard-coded) to the model works fine.
In the callback I add the cuts with

@usercut( cb, model[:u][w] <= C + dot(c, model[:z]) )

where :u and :z are decision vectors, C is a constant c a vector, and cb::CPLEX.CplexCutCallbackData.

Is there maybe anything wrong with that, or are there some other parameters that force to resolve the LP relaxation after a cut is added?

In JuMP 0.19, we have (temporarily) removed solver-independent callbacks because the implementations differ between solvers and it is almost always necessary to have more direct control over the callback than JuMP 0.18 provides.

Your example is a good demonstration of this.

CPLEX.jl wraps the C interface, so in theory, anything you can do via C you can do via CPLEX.jl. So I would look through the C documentation for inspiration on what to do. I don’t have any concrete advice as I don’t know all the parameters (there are many).

1 Like

Okay, this sounds like bad news to me. Thank you anyway @odow.