Originally posted by: SystemAdmin
Chris,
what you are proposing to do in Concert should work correctly. But as you pointed out, it will be a major performance bottleneck.
The main reason is not so much the duplication of the cuts in your own data structures. The issue is the LP solving.
When you do what you suggest, it means that CPLEX needs to solve all of these LPs from scratch each time. This is typically
much slower than starting from an optimal basis and resolving the LP with the dual simplex after having added some rows or tightened some bounds.
In order to speed-up your Concert approach, you should solve the root relaxation once and store the basis. You should also keep this LP copy instead of throwing it away and constructing it again at every node.
Then, whenever you apply your strong branching procedure, first load in the optimal basis into your LP copy, then apply all necessary changes to reach the current node, and solve the LP. Then, store the new optimal basis in local arrays. Then, start your strong branching loop:
1. load in the optimal basis,
2. add the additional branching constraints,
3. solve and evaluate the LP,
4. remove the additional branching constraints,
5. repeat 1-4 until all branching candidates have been evaluated.
Finally, remove all local constraints to recover your root LP relaxation.
Of course, you can even do more advanced stuff like storing the local optimal bases at every node in the search tree, which would speed-up the initialization procedure you have to apply before going into your strong branching loop.
But overall, even this approach is likely to perform much worse than what you can easily do in the C API. The reason is that in the C API you can access and temporarily manipulate the local LP relaxation directly.
In a C API branch callback, you would query the nodelp with CPXgetcallbacknodelp(). Then, query the optimal basis and dual norms with CPXgetbasednorms(). Then do:
1. load in the basis and dual norms with CPXcopybasednorms(),
2. add the additional branching constraints with CPXaddrows(),
3. solve the LP with CPXdualopt() and query solution information with CPXsolution(),
4. remove the branching constraints with CPXdelrows(),
5. repeat 1-4 until all branching candidates have been evaluated,
6. load in the basis and dual norms with CPXcopybasednorms(),
7. call CPXdualopt() to restore the internal LP state that CPLEX needs to proceed.
I think this should work, but maybe CPLEX does not like you to work directly on the nodelp. If this is the case, then you just need to copy the nodelp locally and work on this local copy instead (which then saves you steps 6 and 7).
Tobias
#CPLEXOptimizers#DecisionOptimization