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

Consider constraints with empty linexpr correctly #237

Merged
merged 1 commit into from Jan 19, 2024
Merged

Consider constraints with empty linexpr correctly #237

merged 1 commit into from Jan 19, 2024

Conversation

sebheger
Copy link
Collaborator

@sebheger sebheger commented Jan 6, 2022

Fixes #213

@sebheger
Copy link
Collaborator Author

sebheger commented Jan 7, 2022

@h-g-s @tuliotoffolo

@CLAassistant
Copy link

CLAassistant commented Jan 11, 2022

CLA assistant check
All committers have signed the CLA.

@tuliotoffolo
Copy link
Contributor

Hi @sebheger, thank you for your contribution. We're now only waiting for you to agree with the Contributor License Agreement (CLA) to merge your pull request.

@sebheger
Copy link
Collaborator Author

@tuliotoffolo Resigned CLA.

@sebheger
Copy link
Collaborator Author

sebheger commented Jan 16, 2022

I recognized that the CI is not including gurobi - and my test cases fail on gurobi. I hadn't installed gurobi on the system where i did the fix.

It says that my infeasible case is unbounded after being solved with gurobi.

@sebheger sebheger changed the title Consider constraints with empty linexpr correctly (#213) DO NOT MERGE Consider constraints with empty linexpr correctly (#213) Jan 16, 2022
@sebheger
Copy link
Collaborator Author

sebheger commented Jan 16, 2022

Ok, after debugged the gurobi part:

 if status == 4:  # INF_OR_UNBD
     return OptimizationStatus.UNBOUNDED

This is an additional thing to fix. See

In order to determine if the model is infeasible or unbounded, you should set the DualReductions parameter to 0, call reset on the model, and optimize once again. The optimization status that is returned should be either INFEASIBLE or UNBOUNDED.

https://support.gurobi.com/hc/en-us/articles/4402704428177-How-do-I-resolve-the-error-Model-is-infeasible-or-unbounded-

@tuliotoffolo
Copy link
Contributor

Indeed... I'll talk to @h-g-s to discuss how we will approach this issue. We may need a "INF_OR_UNBD" status in Python-MIP.

@sebheger
Copy link
Collaborator Author

sebheger commented Jan 17, 2022

Indeed... I'll talk to @h-g-s to discuss how we will approach this issue. We may need a "INF_OR_UNBD" status in Python-MIP.

I would suggest following gurobis suggested approach. To reset the model, set presolves dual_reductions to 0 and "optimize" again. Checking infeasibility for MIP is in most cases done comparably quickly (as long as you don't to know hints about WHY it is infeasible). I guess this gurobi INF_OR_UNBD thing is originated by weak duality. So just knowing that the dual is infeasible, could be both possible status for the primal.

@sebheger sebheger changed the title DO NOT MERGE Consider constraints with empty linexpr correctly (#213) Consider constraints with empty linexpr correctly Jan 17, 2022
@sebheger
Copy link
Collaborator Author

@tuliotoffolo Take a look. Did some beautifications is cbc & tests and introduced a fix for the gurobi status.

@tuliotoffolo
Copy link
Contributor

Thanks, @sebheger. Looks very nice! :)
There's only one thing I would change: I don't think that disabling dual reductions and re-optimizing 'automatically' is the way to go, since depending on the model this may be undesirable. In fact, that's probably the reason why Gurobi does not do so automatically. I will further analyze it, but so far I personally prefer to return "INF_OR_UNBD" and create a function containing your code so that the user can convert "INF_OR_UNBD" into "INFEASIBLE" or "UNBOUNDED".

@sebheger
Copy link
Collaborator Author

@tuliotoffolo I introduced new OptimizationStatus as suggested. I put the code for automatic re-optimization into a comment for the moment. There would be some clarfications needed where to place a method to reoptimize, as the status of an optimization run is only persisted in the Model, but not in GurobiSolver.

@sebheger
Copy link
Collaborator Author

sebheger commented Feb 10, 2022

After I had a look at #184 I am not sure if my fixes solve the overall problem. This should be reported to CBC. It should be ideally supported on CBC side to correctly add empty rows (in the same way as supporting empty colums), which could be later modified by the columns parameter of the variable.

@BramVanroy
Copy link

@sebheger Thank you for your work on this. As far as I understand, you indicate that this is not a full solution to the problem and something would need to change on the side of cbc. Has this be reported to them somewhere?

That being said, I assume that this PR already deals with some issues - hopefully also mine :-) So is there any chance of getting this PR merged and pushed to PyPi? cc @tuliotoffolo

@tuliotoffolo
Copy link
Contributor

Revisiting this pull request: @sebheger, is there any reason for not merging it?

@sebheger
Copy link
Collaborator Author

@tuliotoffolo Feel free to merge it, it solves #237 by a hack. I was hoping it also solves #184, but the segfault still exstists, because both issues arise from an problematic behaviour of the C-api to cbc.

@tuliotoffolo tuliotoffolo merged commit 78ad7e4 into coin-or:master Jan 19, 2024
@tuliotoffolo
Copy link
Contributor

Thanks, @sebheger.
Indeed, it solves #237 by a hack. I'll take a look at CBC's C api and see if I can help there.

termoshtt added a commit to Jij-Inc/ommx that referenced this pull request Jun 27, 2024
Constraint without any decision variable like following causes
segmentation fault in CBC solver with Python-MIP 1.15.
https://github.com/Jij-Inc/ommx/actions/runs/9698846012/job/26766373894

```python
    x = DecisionVariable.continuous(0)
    instance = Instance.from_components(
        decision_variables=[x],
        objective=x,
        constraints=[
            # 1 >= 0 is always true
            Linear(terms={}, constant=1) >= 0,
            x <= 1,
        ],
        sense=Instance.MAXIMIZE,
    )
```

This has been reported in
coin-or/python-mip#213 and some linked issues,
and fixed in coin-or/python-mip#237.

We use latest commit of Python-MIP
coin-or/python-mip@0ccb811
until the next version is released
coin-or/python-mip#384
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Constraint using xsum with empty list is not added to model
4 participants