Forum Discussion
FICO
2 months agoCommunity Manager
How to make cuts added in a preIntsol callback globally valid (root node) instead of local to the current subtree?
I'm using the Xpress Optimizer Java API (com.dashoptimization, Xpress 9.4) to solve a MIP with lazy constraints that are generated dynamically. My constraints are all globally valid — they are not local to any node.
Current approach: I register a preIntsol callback (AbstractPreIntsolListener). When a candidate integer solution is found, I check it, and if it violates one of my lazy constraints I build the cut, presolve it, and add it with prob.addCut(). I've disabled dual reductions (setMIPDualReductions(0)) as required for lazy constraints.
This works correctly, but as I understand it XPRSaddcuts activates the cut at the current node and its descendants only. When the search backtracks above that node, the cut is deactivated (kept in the pool, but no longer in the active LP). Because my cuts are globally valid, this is safe, but it's inefficient: the same infeasible integer solution can be rediscovered elsewhere in the tree, re-triggering my callback to re-derive cuts I already found.
What I want: I'd like each generated cut to be treated as globally valid — effectively added at the root node — so it stays active throughout the whole branch-and-bound tree and is never re-derived.
Is there a way to add a cut from within a callback and have it applied globally (root node), rather than only to the current node's subtree?
2 Replies
- FICOCommunity Manager
Dear Christian,
Many thanks for your prompt and detailed answer!
I will take a look at those links while waiting patiently for new implementations.
Bests,
Emanuele Cutore
- FICOCommunity Manager
Dear Emanuele,
Your approach is correct. Your cuts should be added at integral tree nodes (soltype==0) if the integral solution violates one of your constraints. If the infeasible solution stems from a heuristic (soltype!=0), you can only reject it, not derive a cut from it. In addition, you can hook into the optnode callback to generate violated constraints.
There are a few examples on separating lazy constraints, including in this community: https://community.fico.com/s/question/0D54W00008P73MsSAJ/lazy-cut-callback-in-java. Also check examples around the traveling salesman problem and subtour elimination constraints, available for different APIs: https://examples.xpress.fico.com/example.pl?id=tsp_java.
For the moment, cuts in Xpress are managed locally — it is not possible to add global cuts in the sense of an automation that keeps a cut permanently enforced at the root. We are aware of this limitation and are actively working on solutions that would address use-cases like yours.
Best regards,
Christian Raack
Related Content
Related Content
Are preintsol callbacks threadsafe?
The optimizer documentation states "When the MIP callbacks are called they are MUTEX protected to allow non threadsafe user callbacks." In my Java code for one-tree Benders, if I specify a single thr...9 months agoPlace FICO® Xpress Optimization ForumFICO® Xpress Optimization Forum3 unread comments3 unread2Views0likes3CommentsVariable names in callback (Java API)
I construct a cut in a preintsol callback using variables from the model containing the callback. When constructing the model, I give the variables names (using withName(...)) and store them in a vec...9 months agoPlace FICO® Xpress Optimization ForumFICO® Xpress Optimization Forum4 unread comments4 unread1View0likes4CommentsVariable object mapping issue in Python Callbacks with Presolve enabled
Hi, I am implementing a Branch-and-Cut algorithm using the Xpress Python interface. I have structured my code as a class where I create variables (using xp.var) and store them in a dictionary attrib...8 months agoPlace FICO® Xpress Optimization ForumFICO® Xpress Optimization Forum6 unread comments6 unread0Views0likes6Comments