As part of issue1224, we removed support for two-sided constraints. Most of our constraints either had a trivial bound in one direction, so they essentially were already one-sided.
In the Rankooh & Rintanen implementation of delete-relaxation constraints, we had one constraint with a lower bound of 0 and an upper bound of 1. The upper bound was implied by the bounds on the LP variables, so we dropped it when moving to one-sided constraints. Experiments showed that the performance of SoPlex was negatively impacted by this, i.e., that SoPlex preferred
0 <= expression <= 1
over
0 <= expression.
Even adding two one-sided constraints, i.e.,
0 <= expression
expression <= 1
did not improve performance.
In this issue we want to look into ways of retrieving this lost performance, ideally without losing the performance we gained in CPLEX from the switch to one-sided constraints.
One option is to support both one-sided and two-sided constraints in our interface. This would require book-keeping to support the constraints that are "unnatural" for a solver (one-sided for SoPlex, two-sided for CPLEX/Gurobi). In particular, two-sided constraints can be supported with range-constraints in CPLEX/Gurobi but those are always satisfiable. They cannot represent trivially unsatisfiable bounds like 1 <= expression <= 0. Before merging issue1224 we had code that dealt with this (see the commit merging issue1224) and we might have to reintroduce some of this, trading off between code complexity and performance.
Another option might be to support "optional/implied bounds" that can be ignored by a particular solver. In the example above, treating the upper bound of 1 as an optional bound would allow CPLEX/Gurobi to ignore it and Soplex to use a two-sided constraint. It would probably work for the only case we have but it might be too specialized of an interface.
A third option to explore would be to see if we can get the performance back with two one-sided constraints, i.e.,
0 <= expression
expression <= 1
if we enable presolving. Presolving is currently switched off for SoPlex as it was not generally useful, but maybe we want to make a per-heuristic setting and maybe this issue changes the trade-off.
|