Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bridge] implement special case for x != y in CountDistinctToMILPBridge #2416

Merged
merged 5 commits into from Feb 5, 2024

Conversation

odow
Copy link
Member

@odow odow commented Feb 2, 2024

Closes #2405

This PR implements a much stronger reformulation for the special case of [2, x ,y] in CountDistinct which is created by [x, y] in AllDifferent(2), a.k.a. x != y.

@odow
Copy link
Member Author

odow commented Feb 2, 2024

I don't know why you can't see the coverage: https://app.codecov.io/github/JuMP-dev/MathOptInterface.jl/pull/2416

@LebedevRI
Copy link

@odow FWIW, thank you for looking into this!
It will be unfortunate if this expansion will still not handle the bound-less case, but if that is what you think is best...

@odow
Copy link
Member Author

odow commented Feb 3, 2024

but if that is what you think is best...

Can you provide a reformulation that would let us write this as a MILP (excluding indicator constraints) without knowing the bounds?

Copy link

@LebedevRI LebedevRI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Speaking of proofs, can you show the proof?
Are bounds inclusive or exclusive?
This doesn't quite proof for me: https://godbolt.org/z/3nEEdr1hj https://alive2.llvm.org/ce/z/tUeBwc
https://godbolt.org/z/Mc87q4cjf https://alive2.llvm.org/ce/z/otmnsE

src/Bridges/Constraint/bridges/count_distinct.jl Outdated Show resolved Hide resolved
@odow
Copy link
Member Author

odow commented Feb 3, 2024

I don't understand the relevance of the links.

We're looking for a MILP reformulation of

| x | >= 1

where x is free, and we can't choose an arbitrary big-M like M = 1e6

@LebedevRI
Copy link

I don't understand the relevance of the links.

Link 1 shows the true variant of the constraint (src), and naive re-implementation of this constraint in C (tgt),
Link 2 feeds the implementations to an SMT solver, which says that they are not equivalent.

@odow
Copy link
Member Author

odow commented Feb 3, 2024

Ugh. I can't read or type. I typed z-1 instead of 1-z at the top and then blindly followed through without thinking.

@LebedevRI
Copy link

but if that is what you think is best...

Can you provide a reformulation that would let us write this as a MILP (excluding indicator constraints) without knowing the bounds?

Back when writing that comment, i didn't quite noticed that this was using yet another reformulation,
one without indicator constraints. I don't know if this one can be formulated without bounds.

It would be nice to either see either an exhaustive (correctness) test for this, or a non-manual proof.
But please feel free to ignore me on that! :)

@odow
Copy link
Member Author

odow commented Feb 3, 2024

It would be nice to either see either an exhaustive (correctness) test for this, or a non-manual proof.

This hints at a much larger issue. We don't have any tools to check the correctness of JuMP models, and it is very easy (as just demonstrated) to make small mistakes. I'll open a JuMP issue.

@odow
Copy link
Member Author

odow commented Feb 3, 2024

See jump-dev/JuMP.jl#3664

@odow odow merged commit f5d8efa into master Feb 5, 2024
17 checks passed
@odow odow deleted the od/perf-count-distinct branch February 5, 2024 20:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

Add support for NotEqualTo !=
2 participants