I am facing a problem with JuMP 0.21.4 and Julia 1.6.2. I am working with an Integer Programming model using CPLEX 12.10 and I using callbacks to add some cuts, however, I need these cuts to be added only when the callback is at the root, i.e, I need to add these cuts only when the node depth is 0. Hence, I would like to know if anyone has done something similar. I have used such functionality before when working with another programming language (IBM Documentation).
Thank you for your time.
ps: Note that I am not talking about the callback node status (Callbacks · JuMP).
Hi, I am sorry for reopening this thread. But I am still struggling to get the branch-and-bound depth through a solver-dependent callback. Follows an MWE based on the example provided at here.
When executing the above code, the following output is given:
ERROR: LoadError: MethodError: Cannot `convert` an object of type Int64 to an object of type CPXCALLBACKINFO
As you can see, I already tried replacing the call CPXcallbackgetinfodbl with CPXcallbackgetinfoint and CPXcallbackgetinfolong. But both changes lead to the same error. I suppose that I am using the wrong function or the wrong flag, i.e. I should use something other than CPX_CALLBACK_INFO_NODE_DEPTH. I would like to know if anyone has any documentation about this.
Very thank you for your answer. The code is now executing, however, I think the results are not right. I used the commands as you suggested resulting in the function below:
And I getting really strange results, specifically very big numbers, such as 52465968, 140258102699840,…
I think that the conditions (CPXcallbackcandidateispoint(cb_data, ispoint_p) != 0 || ispoint_p[] == 0) are not enough. Which is strange, since according to the documentation this is a valid condition. If anyone has ever faced such a thing I would like to hear something.
Quick thought: are you sure the last bracket is where you want it? If this is a Bool comparison, I would use false over 0, or do you want ispoint_p[] == 0)?
function my_callback_function(cb_data::CPLEX.CallbackContext, context_id::Clong)
if context_id != CPX_CALLBACKCONTEXT_CANDIDATE
return
end
ispoint_p = Ref{Cint}()
ret = CPXcallbackcandidateispoint(cb_data, ispoint_p)
if ret != 0 || ispoint_p[] == 0
return
end
depth = Ref{CPXLONG}()
ret = CPXcallbackgetinfolong(cb_data, CPXCALLBACKINFO_NODEDEPTH, depth)
@assert ret == 0
println(depth[])
end
You need to check the return code to see if the call succeeded. I’m guessing it didn’t. Probably because there was no node and the problem was solved at the root node via heuristics?
More generally, you need to read the CPLEX documentation in more detail: IBM Documentation
You say you only want to add cuts at the root, but CPX_CALLBACKCONTEXT_CANDIDATE indicates that you have a valid integer solution. Perhaps you want CPXCALLBACKINFO_NODECOUNT or CPXCALLBACKINFO_NODEUID? instead?