Greetings!

I am working on my master thesis on a large-scale flow problem, where I have implemented a surrogate model derived from a neural network in the form of a set of mixed integer linear constraints which replaces a complicating non-convex, non-linear constraint. Luckily, that part is working fine, but now I want to implement my own custom branching strategy to test if I can speed up the solution time.

I have looked at my options, and it seems that CPLEX is one of (if not the only) commercial solver that will allow me to make my own custom branching strategy. To my understanding, what I am looking to use is the CPX_CALLBACKCONTEXT_BRANCHING callback, but I do not really understand how it works especially from a Julia/JuMP perspective, as they only have examples/pseudocode for the C api.

I am looking to do some simple calculations on some continuous variables, and based on that outcome, choose an associated fractional binary to branch on.

I have previously used Gurobi callbacks with solver-independent MOI callbacks (I fed a heuristic solution to the MIPnode) and that was very simple to implement. Looking through source code and examples online for the CPLEX solver-dependent callbacks though, it seems a bit more complicated. At least to my understanding, it does not fit into the categories of either âLazyConstraintsâ âHeuristicSolutionâ or âUserCutsâ, so I cannot use the syntax for any of these e.g. `MOI.submit(model, MOI.LazyConstraint(cb_data), con)`

.

Anyway, while I have decent experience with coding and programming, mostly through Python and a bit of Julia, I have a hard time trying figure out exactly what kind of syntax etc. I am looking for.

Hope someone can help! If you need more information please let me know and Iâll be happy to provide you.

TL;DR I hope someone can help, maybe with a dummy example, on how to use the solver-dependent callbacks in CPLEX in a Julia context.

UPDATE:

I tried to look a bit more into the CPLEX documentation and the following example which seems to do something more like what i am looking for, but not exactly. I think I need to call the following function `status = CPXcallbackmakebranch(context, varcnt, varind, varlu, varbd, rcnt, nzcnt, rhs, sense, rmatbeg, rmatind, rmatval, nodeest, seqnum_p)`

to create the desired branch after i have defined the desired fractional binary to branch on. Exactly *how* to provide the arguments correctly, i am still quite confused about thoughâŚ I found this IBM Documentation that describes the parameters needed, but i donât understand why i need to provide constraints, I only want to branch on a single variable, so in my mind, only the new upper and lower bound for the to child nodes are relevant, i guess there is obviously something about the function i just donât understand

For context, here is my callback function so far:

```
function my_callback_function(cb_data::CPLEX.CallbackContext, context_id::Clong)
if context_id == CPX_CALLBACKCONTEXT_BRANCHING
@info "callback called"
# Before querying `callback_value`, you must call:
CPLEX.load_callback_variable_primal(cb_data, context_id)
# get the relevant values from the callback
y_val = callback_value.(cb_data, m[:y])
# y_hat_val = callback_value(cb_data, y_hat)
xp_val = callback_value.(cb_data, m[:xp])
xn_val = callback_value.(cb_data, m[:xn])
b_val = callback_value.(cb_data, m[:b])
#Compute the maximum distance to the ReLU hyperplane
d = (.-xn_val.+xp_val.+1)./(y_val.+1)
#get the index of the associated fractional binary (if the ReLU is not enforced it will be > 1 and otherwise = 1)
b_chs = argmax(d)
@info "b_chs: $(b_chs)"
#now create the child nodes (somehow)
#Somehow add the appropriate arguments to the function call...
# status = CPXcallbackmakebranch(context, varcnt, varind, varlu, varbd, rcnt, nzcnt, rhs, sense, rmatbeg, rmatind, rmatval, nodeest, seqnum_p)
#I only know that the context needs to be cb_data, and i think that the varind should be b_chs, but I don't know the rest of the arguments...
status = CPXcallbackmakebranch(cb_data, ???, b_chs, ???, ???, ???, ???, ???, ???, ???, ???, ???, ???, ???)
else
return
end
end
```

Best,

Valdemar