cvxpy: Linear mixed-integer solver problem is failing with GLPK-MI
Describe the bug Linear mixed-integer solver problem is failing with GLPK-MI (and used to work in older versions, namely 1.0.25, the one I used to design my problem).
To Reproduce Here’s the smallest test I could come up with. Sorry for the size of the constraint matrices and the “real” values, but I couldn’t reproduce that bug with small handcrafted matrices.
import cvxpy as cp
import numpy as np
x = cp.Variable(shape=10, boolean=True)
disorders = np.array([0.36, 0.36, 0.36, 0.36, 1., 1., 1., 1., 1., 1., ])
A = np.array([[1, 0, 0, 0, 0, 1, 0, 0, 0, 0.],
[0, 1, 0, 0, 0, 0, 1, 0, 0, 0.],
[0, 0, 1, 0, 0, 0, 0, 1, 0, 0.],
[0, 0, 0, 1, 0, 0, 0, 0, 1, 0.],
[1, 1, 1, 1, 1, 0, 0, 0, 0, 0.]])
obj = cp.Minimize(disorders.T @ x)
constraints = [cp.matmul(A, x) == 1]
prob = cp.Problem(obj, constraints)
optimal_disorder = prob.solve()
print(f"Optimal disorder is {optimal_disorder}")
Expected behavior
It should come up with a solution. Adding verbose=True did not print anything useful that might help me solve that bug.
Output
Traceback (most recent call last):
File "/home/hadware/Code/CoML/test_cvxpy/linsolver_test.py", line 16, in <module>
optimal_disorder = prob.solve()
File "/home/hadware/Code/CoML/test_cvxpy/venv/lib/python3.6/site-packages/cvxpy/problems/problem.py", line 396, in solve
return solve_func(self, *args, **kwargs)
File "/home/hadware/Code/CoML/test_cvxpy/venv/lib/python3.6/site-packages/cvxpy/problems/problem.py", line 748, in _solve
self.unpack_results(solution, solving_chain, inverse_data)
File "/home/hadware/Code/CoML/test_cvxpy/venv/lib/python3.6/site-packages/cvxpy/problems/problem.py", line 1062, in unpack_results
"Try another solver, or solve with verbose=True for more "
cvxpy.error.SolverError: Solver 'GLPK_MI' failed. Try another solver, or solve with verbose=True for more information.
Version
- OS: Ubuntu 18.04, python 3.6, venv
- CVXPY Version: 1.1.4 (same bug on 1.1.3)
- CVXOPT Version: 1.2.5
About this issue
- Original URL
- State: open
- Created 4 years ago
- Comments: 19 (6 by maintainers)
Update: see also comment below.
I’m having similar issues with a similar problem, I can also reproduce the problem in the bug description. After a bit of trial and error, I suspect that when using GLPK_MI, equality constraints are not supported or not working correctly. There might be an easy workaround by adding the constraint with inequalities in both directions. At least for your example it seems to spit out the same result as it does with Gurobi. Disclaimer: lots of guess work involved here 😃
Environment
Complete cona environment
Minimal example 1
the original example with making the solver choice explicit via
solver=cp.GLPK_MI.Output:
Minimal example 2
same as example 1, but replacing the constraint with two inequalities (and adding more output).
Output:
Minimal example 3
Same thing with Gurobi and equality constraint for cross-checking the solution:
Output:
We’re pushing SCIP now: https://www.cvxpy.org/install/#install-with-scip-support It’s unfortunate that people now need to install a solver to solve mixed integer problems. The issue is that the solutions from ECOS_BB were often totally wrong.
It’s actually pretty simple:
cvxopt.glpk.ilp()doesn’t support linear programs without inequality constraint, so it’s not really a bug. CVXPY could probably pass on the error message to the user in a nicer format, but I wouldn’t say this is a bug. But it should be possible to add support for it easily, I’m just not sure what’s the right way to go here. Is there any reason, why one would require at least one in-equality constraint for the solver?I guess we could simply use the equality constraints also for the in-equality constraints if there is no in-equality constraint, i.e. add the workaround from my previous post to CVXPY. Or we could add just one (arbitrary?) in-equality constraint as equality constraint. I guess solving a linear program without any constraints, doesn’t make sense, right? So there must be some constraint. Is there a performance or numerical difference which constraint is chosen? Is there any better solution than this? Maybe it needs to be fixed upstream in CVXOPT?
It might be helpful to improve error handling es well. Debugging might be easier, if a an error such as “m must be a positive integer” is passed to the user.
The docstring of
cvxopt.glpk.ilp():I’m new to the internals of CVXPY, but would be happy to provide a patch if somebody could help me a bit along the way.
Woah great work @lumbric ! That’s actually quite an hacky yet elegant way to make this work. I’ll try to see if my unit tests fail or not when I’m using this workaround.