Skip to content

linprog returns 'infeasible' for simple unbounded case #11617

@andrewdelong

Description

@andrewdelong

The linprog with interior-point method can return 'infeasible' for cases where the problem is unbounded.

Reproducing code example:

If you enter the simple LP

min  x1
s.t. x1 <= -1

then pre-solve correctly detects that it's unbounded:

c = [1.]
A_ub = [[1.]]
b_ub = [-1.]
scipy.optimize.linprog(c, A_ub, b_ub, None, None, bounds=(None, None), method='interior-point')
     con: array([], dtype=float64)
     fun: -inf
 message: 'The problem is (trivially) unbounded because there are no non-trivial constraints and a) at least one decision variable is unbounded above and its corresponding cost is negative, or b) at least one decision variable is unbounded below and its corresponding cost is positive. '
     nit: 0
   slack: array([inf])
  status: 3
 success: False
       x: array([-inf])

But if you convert that LP to standard form

min  x1      - x3
s.t. x1 + x2 - x3 = -1
x1,  x2,  x3 >= 0

you find that linprog (interior-point only) considers it infeasible:

c = [1., 0., -1.]
A_eq = [[1., 1., -1.]]
b_eq = [-1.]
scipy.optimize.linprog(c, None, None, A_eq, b_eq, method='interior-point')
     con: array([-33.89879])
     fun: -1735502760.3390775
 message: 'The algorithm terminated successfully and determined that the problem is infeasible.'
     nit: 3
   slack: array([], dtype=float64)
  status: 2
 success: False
       x: array([1.40062e+09, 1.73550e+09, 3.13612e+09])

The bug is very sensitive to coefficients: changing to c = [.9, 0., -.9] correctly returns 'unbounded.'

Possible cause:

The cause seems to be the logic below:

# [4] Lemma 8.4 / Theorem 8.3
if b.transpose().dot(y) > tol:
status = 2
else: # elif c.T.dot(x) < tol: ? Probably not necessary.
status = 3

As far as I can tell, the bug occurs because, even though -c.T @ x (0.8669123426) is a large positive value and thus kappa > 0 is due to unboundedness rather than infeasibility, we still have b.T @ y (0.0000000151) slightly greater than tol (0.0000000100), possibly due to numerical inaccuracies. The above logic falsely reports 'infeasible' in such cases rather than unbounded.

Scipy/Numpy/Python version information:

scipy=1.4.1 (or 1.5.0.dev0+9beb4c5)
numpy=1.18.1 (or 1.19.0.dev0+f1a247f)
sys.version_info(major=3, minor=8, micro=1, releaselevel='final', serial=0)

Metadata

Metadata

Assignees

No one assigned

    Labels

    defectA clear bug or issue that prevents SciPy from being installed or used as expectedscipy.optimize

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions