DisjunctiveProgramming.jl icon indicating copy to clipboard operation
DisjunctiveProgramming.jl copied to clipboard

Do Not Merge Yet: Add MOI Disjunction Set Reformulation

Open pulsipher opened this issue 2 years ago • 8 comments

This adds the MOIDisjunction reformulation method which transforms disjunctions in vector constraints that use DisjunctionSet. This enables us to pass disjunctions directly down to the MOI level.

pulsipher avatar Oct 12 '23 19:10 pulsipher

As an update, it seems MOI bridges will likely not work with disjunctions. The problem is that each disjunct can contain an arbitrary number of constraints of any type (including other disjunctions). For a bridge to work, MOI needs to be able to infer want reformulation constraints will be constructed based on the set type. With:

struct DisjunctionSet{S <: _MOI.AbstractSet} <: _MOI.AbstractVectorSet 
    dimension::Int
    disjunct_indices::Vector{Int}
    constraint_sets::Vector{Vector{S}}
end

we will most often end up with something like DisjuctionSet{MOI.AbstractSet} which doesn't tell us what type of constraints it contains. Alternatively, we could use a tuple to put all the constraint set types as parametric types:

struct DisjunctionSet{T <: Tuple} <: _MOI.AbstractVectorSet 
    dimension::Int
    disjunct_indices::Vector{Int}
    constraint_sets::T # flatten everything into a tuple
end

Now T will contain all constraint set types, but to make a MOI bridge we would have to account for every concrete typed case. This leads to an infinite number of combinations, since there can be any number of disjuncts and constraints with any type.

So, in the end, it is possible to represent disjunctions in MOI, but bridges won't be practical to implement. However, solvers (e.g., ToQUBO.jl) can still support DisjunctionSets directly. Ultimately, we can make an MOI solver layer similar to ParametricOptInterface that converts DisjunctionSets into forms that other solvers can handle. Moreover, such a layer could support more advanced solution techniques like logic-based outer approximation.

pulsipher avatar Oct 13 '23 13:10 pulsipher

After talking offline with @hdavid16, another option to is add a canonicalized disjunction set where all the constraints are converted to inequalities first:

struct DisjunctionSet{T <: Real} <: _MOI.AbstractVectorSet 
    dimension::Int
    disjunct_indices::Vector{Int}
    constraint_sets::Vector{Vector{MOI.LessThan{T}}}
end

This would require more processing upfront, change the structure, and potentially exclude some constraint types (e.g., cones), but this would be easy to implement a bridge for.

pulsipher avatar Oct 13 '23 16:10 pulsipher

Codecov Report

Attention: 26 lines in your changes are missing coverage. Please review.

Comparison is base (3af182e) 98.91% compared to head (e0570d8) 96.19%.

Additional details and impacted files
@@            Coverage Diff             @@
##           master      #71      +/-   ##
==========================================
- Coverage   98.91%   96.19%   -2.72%     
==========================================
  Files          10       11       +1     
  Lines         921      947      +26     
==========================================
  Hits          911      911              
- Misses         10       36      +26     
Files Coverage Δ
src/datatypes.jl 100.00% <ø> (ø)
src/moi.jl 0.00% <0.00%> (ø)

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.

codecov[bot] avatar Oct 26 '23 18:10 codecov[bot]

@bernalde and @pedromxavier I think this PR gives you the MOI representation that you need. Namely, the addition of DisjunctionSet <: MOI.AbstractVectorSet. Let me know your thoughts and if it looks good, I will add tests and we can merge this for you to use.

pulsipher avatar Nov 09 '23 03:11 pulsipher

It looks good to me. I'd be curious to see the tests to see how to interact with the new code.

bernalde avatar Nov 09 '23 18:11 bernalde

Should there be a MOI.get interface for accessing the contents of the Disjunction Set?

pedromxavier avatar Nov 09 '23 19:11 pedromxavier

Should there be a MOI.get interface for accessing the contents of the Disjunction Set?

Any suggestions on what the input and output would be precisely?

pulsipher avatar Nov 09 '23 19:11 pulsipher

Any suggestions on what the input and output would be precisely?

@bernalde @pedromxavier

hdavid16 avatar Dec 18 '23 13:12 hdavid16