Search code examples
pythonoptimizationscipylinear-programming

Converting bounds to inequality constraints does not yield the correct answer


I have a linear program in the general form:

https://i.sstatic.net/Nqnei.png

I was playing around with scipy's linprog. In the documentation they provide an example:

https://i.sstatic.net/4Y7Q8.png

They provide the code:

c = [-1, 4]
G = [[-3, 1], [1, 2]]
h = [6, 4]
x0_bounds = (None, None)
x1_bounds = (-3, None)
from scipy.optimize import linprog
res = linprog(c, A_ub=A, b_ub=b, bounds=[x0_bounds, x1_bounds])

Linprog can't handle “greater than” inequality constraint so we need to convert to “less than” inequality constraint. Note that they explicitly input the bounds (the inequality x1≥-3 part).

I was thinking that I could instead incorporate the bounds into the general inequality matrix G.

I have the function:

import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import linprog

def LP(c,d,G,h,A,b, method = 'revised simplex'):
  res = linprog(c, A_ub = G, b_ub = h, A_eq = A, b_eq = b, method = method)
  if res.success == True:
    print('The optimization was successful in', res.nit, 'iterations')
    print('The optimal solution is:', res.x)
    print('The objective function is equal to:', res.fun+d)
    return res.x
  if res.success == False:
    print('The optimization was not successful')
    if res.status == 1:
      print('Iteration limit reached')
    if res.status == 2:
      print('Problem appears to be infeasible')
    if res.status == 3:
      print('Problem appears to be unbounded')
    if res.status == 4:
      print('Numerical difficulties encountered')

with the parameters:

c = [-1,4]
d = 0
G = [[-3,1],[1,2],[0,-1]]
h = [6,4,3]
A = None
b = None

Running this I get the optimal solution x = [4., 0.] with the objective obj = -4. However in the documentation they say that the optimal solution is [10., -3.] with the objective obj = -22. Both the solutions are in the feasible set so their solution is clearly better.

Does anyone know why I don't get the same answer as the one in the documentation?

Link to the documentation: https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.linprog.html


Solution

  • To cite the docs:

    Note that by default lb = 0 and ub = None unless specified with bounds.

    Thus, you need to explicitely specifiy that there are no bounds on the optimization variables:

    bounds = [(None, None), (None, None)]
    res = linprog(c, A_ub = G, b_ub = h, A_eq = A, b_eq = b, bounds=bounds, method = method)