mtanneau / MathOptPresolve.jl

Presolve routines for mathematical optimization
Mozilla Public License 2.0
23 stars 5 forks source link

MIP presolve reductions roadmap #9

Open mtanneau opened 3 years ago

mtanneau commented 3 years ago

Coarse roadmap towards implementing the reductions described in this paper (which is, AFAIK, the most comprehensive and recent paper on the subject).

The table below follows the paper's structure, namely:

  1. Individual row reduction
  2. Individual variable reduction
  3. Multiple row reductions
  4. Multiple variable reductions
  5. Full-problem reduction

The second and third columns indicate whether each reduction is applicable to LP/MIP models (see detailed legend below)

Reduction LP MIP Current progress
3.1 Redundant constraints ✔️ ✔️ LP:🚧 📝; MIP: 🙅
3.2 Bound strengthening ✔️ ✔️ LP:🚧 📝; MIP: 🙅
3.3 Coefficient strengthening ✔️ 🟢 #14
3.4 C-G strengthening ✔️ 🙅
3.5 Euclidean and modular inverse ✔️ 🙅
3.6 Single-row probing ✔️ 🙅
3.7 SOS reductions ✔️ 🙅
4.1 Fixed variables ✔️ ✔️ 🟢 #7
4.2 Rounding integer bounds ✔️ 🚧 #8
4.3 Strengthen SC/SI bounds ✔️ 🙅
4.4 Dual fixing ✔️ ✔️ 🙅
4.5 Implied-free variables ✔️ ✔️ LP:🚧 📝; MIP: 🙅
5.1 Redundancy detection ✔️ ✔️ 🙅
5.2. Parallel rows ✔️ ✔️ 🙅
5.3 Non-zero cancellation ✔️ ✔️ 🙅
5.4 (multi-row) bound strengthening ✔️ ✔️ 🙅
5.5 Clique merging ✔️ 🙅
6.1 Dual fixing extension ✔️ 🙅
6.2 Redundant penalty variables ✔️ ✔️ 🙅
6.3 Parallel columns ✔️ ✔️ 🙅
6.4 Dominated columns ✔️ ✔️ 🙅
7.1 Symmetric variables ✔️ 🙅
7.2 Probing ✔️ 🙅
7.3 Disconnected components ✔️ ✔️ 🙅
7.4 Almost disconnected components ✔️ ✔️ 🙅
7.5 Complementary slackness ✔️ 🙅
7.6 Implied integer ✔️ 🙅

Legend:

cc @joehuchette @BochuanBob

joehuchette commented 3 years ago

cc @Anhtu07

mtanneau commented 3 years ago

After looking at this I'm wondering whether the approach I proposed in #7 may be a bit off-course.

It might make more sense to organize things in a bottom-up approach:

  1. Low-level rules that apply a single reduction, e.g., fix a single variable, tighten individual variable bounds, etc.
  2. Some middle-level strategies that combine individual rules in a "simple"-ish way, for instance:
    • Eliminate all fixed variables
    • Check all rows for redundancy
    • etc.
  3. High-level loop

In the context of #7, this would mean the following modifications:

joehuchette commented 3 years ago

In some sense this is kind of already what we have in #7 with the inner loop over remove_fixed_variable! instead of through apply!.

What does this design buy us? Is there utility in applying a FixIndividualVariable reduction to only a subset of the variables at a time? I agree that going through apply! is likely a better design. Just trying to figure out if this buys us anything extra.

mtanneau commented 3 years ago

I'm still brainstorming, since I think this is an important design decision. I like more the idea of a consistent syntax across the code, and of building things on top of individual, self-contained reductions.

What does this design buy us?

Feature-wise, nothing. It's more a matter of consistency across the code.

Is there utility in applying a FixIndividualVariable reduction to only a subset of the variables at a time?

If you're inside a loop that fixes all variables, then no :) But this reduction may be called from somewhere else.

joehuchette commented 3 years ago

+1 to unifying them through the apply! interface. Conceivably you might want to call FixIndividualVariable in a separate presolve routine.

mtanneau commented 3 years ago

This will leave one last thing to discuss/validate: the implementation of pre- and post-crush.

Currently, this is done through PresolveTransformations as follows:

Some low-level rules will inevitably be intrinsically tied to certain transformations (a.k.a reductions), but I think we should keep the distinction between the two. Naming-wise, we currently have the rule FixIndividualVariable and the transformation FixedVariable, which can be confusing. I'm trying to think of a less ambiguous naming convention (preferably without appending Rule or Reduction everywhere), suggestions are welcome.

joehuchette commented 3 years ago

FWIW I don't find the distinction between FixIndividualVariable (or FixVariable) and FixedVariable. After thinking for a few minutes, I'm not sure I can come up with a better naming scheme.

mtanneau commented 3 years ago

I don't find the distinction between FixIndividualVariable (or FixVariable) and FixedVariable

The former is a rule: "If variable j has its lower and upper bound equal, eliminate it". The latter is a reduction: "Variable j has been fixed to its lower bound".

I make the distinction for 2 reasons:

Agreed, in the case of FixVariable and FixedVariable, these are fairly low-level components, and they are very closely related. The least-worst naming convention I can come up with is:

joehuchette commented 3 years ago

Sorry, omitted some crucial words in my response: I don't find it all that confusing that the names are close. I actually guessed your naming convention from the single example, so I think it's not all that bad :)