8000 PuLP integration, cbcModel.status, variable names, readMPS, etc. · Issue #206 · coin-or/CyLP · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

PuLP integration, cbcModel.status, variable names, readMPS, etc. #206

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

Open
pchtsp opened this issue Mar 19, 2025 · 6 comments
Open

PuLP integration, cbcModel.status, variable names, readMPS, etc. #206

pchtsp opened this issue Mar 19, 2025 · 6 comments

Comments

@pchtsp
Copy link
pchtsp commented Mar 19, 2025

I'm trying to integrate this package as an optional dependency of PuLP, as an alternative to distribute the cbc binary.

You can see the progress here: https://github.com/coin-or/pulp/blob/60579dc516c55c63b603f139e2b823de6a1b2d31/pulp/apis/coin_api.py#L872

I've been encountering a number of issues.

I've tried to follow the documentation on CyClpSimplex and CyCbcModel.

It seems that cbcModel.status returns "relaxation infeasible" on optimal problems, where the log says is Optimal.

What's the correct way to get the correct status after solving a problem? I attach a few mps with

filename: test_continuous-pulp.txt
cbc logs say: Optimal
cbc.status returns: relaxation infeasible
cbc.solve() returns: 0


The return code from cbcModel.solve() returns 0 (which I interpret as Optimal) when the log status shows "Linear relaxation infeasible".

filename: test_infeasible-pulp.txt
cbc logs says: Linear relaxation infeasible
cbc.status returns: relaxation infeasible
cbc.solve() returns: 0

Result - Linear relaxation infeasible


Also, how do I solve maximization problems? Do I need to invert the objective functional myself? Or is there a way to communicate this when loading the MPS file?

filename: test_continuous_max-pulp.txt


Finally, how do I access the variables by name when I load the MPS file as input with CyClpSimplex.readMps?

CyClpSimplex.variables returns an error
CyClpSimplex.variableNames is empty

test_infeasible-pulp.txt
test_continuous-pulp.txt
test_continuous_max-pulp.txt

@pchtsp pchtsp changed the title cbcModel.status PuLP integration, cbcModel.status, variable names, readMPS, etc. Mar 20, 2025
@tkralphs
Copy link
Member

I'll have to do a little checking to make sure when I have a little time to devote to this, but off the top of my head, the return code from cbc.solve() is probably not a status and might not be that meaningful. Your results above look correct and consistent. It's possible that the variable names don't get properly set when reading from an MPS file, since this is not how people usually use CyLP. That could be a bug, but there should be a fix.

@pchtsp
Copy link
Author
pchtsp commented Mar 24, 2025

thanks. Let me know if you need anything else from my side. I'm excited to have the possibility to add callbacks to cbc.

@tkralphs
Copy link
Member
tkralphs commented Mar 25, 2025

Just looking at this briefly, it does seem that the variable names are not extracted when reading an MPS file. I think it's not too hard to see how this all hangs together. The files that would need to be modified to add this capability are (I think):
https://github.com/coin-or/CyLP/blob/master/cylp/cpp/ICoinMpsIO.hpp
https://github.com/coin-or/CyLP/blob/master/cylp/cpp/ICoinMpsIO.cpp
https://github.com/coin-or/CyLP/blob/master/cylp/cy/CyCoinMpsIO.pyx
What's needed is to expose the relevant functions in the CoinMpsIO class of CoinUtils and then use them within the readMps method of the CyCoinMpsIO class to populate the relevant Python data structures. A PR would be great. Otherwise, it may be a bit of time before I get to adding this.

@tkralphs
Copy link
Member

There seems to be a bit of a disconnect in how this is implemented. The query method for variable names seems to be querying Clp, which would be fine if we were using Clp's readMps method (which wraps the one in CoinUtils), but we are directly using the CoinUtils method.

@pchtsp
Copy link
Author
pchtsp commented Mar 28, 2025

thanks for checking @tkralphs . I'd love to help with a PR but my C++ skills are very rusty.

What about the first issue I mentioned. Where the log says "Optimal" (and it's the correct message) but the cbc.status property returns "relaxation infeasible".

Thanks again.

@tkralphs
Copy link
Member
tkralphs commented Apr 12, 2025

Looking at this more closely, there is a simpler fix. CyClpSimplex.readMps() has an optional argument keepNames that is False by default. The following works:

from cylp.cy import CyClpSimplex
s = CyClpSimplex()
s.readMps('rentacar.mps', True)
s.variableNames

We should probably just make it True by default, since it doesn't hurt unless you are really trying to economize on memory. Also, we could pull the names into the CyLP model that can be constructed after reading the MPS file, which I don't think is done currently.

For your other question, the return code of cbc.solve() is not a status and shouldn't be interpreted as such. Your previous results look correct and consistent.

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

No branches or pull requests

2 participants
0