14

I'm trying to solve this linear programming function with the restraints shown below, the answer for x1 and x2 should be 2 and 6 respectively, and the value of the objective function should be equal to 36. The code that I wrote gives me as answers 4 and 3. What may I be doing wrong? Function to maximize z=3*x1 + 5*x2. Restraints are x1 <= 4;2*x2 <=12; 3*x1 + 2*x2 <= 18; x1>=0;x2>=0.

import numpy as np
from scipy.optimize import minimize
def objective(x, sign=1.0):
    x1 = x[0]
    x2 = x[1]
    return sign*((3*x1) + (5*x2))
def constraint1(x, sign=1.0):
    return sign*(3*x[0] +2*x[1]- 18.0)
x0=[0,0]

b1 = (0,4)
b2 = (0,12)
bnds= (b1,b2)
con1 = {'type': 'ineq', 'fun': constraint1}

cons = [con1]
sol = minimize (objective,x0,method='SLSQP',bounds=bnds,constraints=cons)

print(sol)
Stelios
  • 5,271
  • 1
  • 18
  • 32
JM Esgar
  • 141
  • 1
  • 1
  • 3
  • Thank you @Stelios ,I just made the changes based on your suggestions and get the answer. I got -35.99, I guess the negative sign is because the algorithm give the answer based on a minimize asumption instead of maximize. – JM Esgar May 02 '17 at 01:41

2 Answers2

16

Your code has the following issues:

  • The way you are passing your objective to minimize results in a minimization rather than a maximization of the objective. If you want to maximize objective with minimize you should set the sign parameter to -1. See the maximization example in scipy documentation.
  • minimize assumes that the value returned by a constraint function is greater than zero. Therefore, the way you have written your constraint implies that 3*x1 + 2*x2 - 18.0 >=0, whereas the actual constraint employs <=.
  • The upper bound in b2 does not correspond to the bound implied by the constraint 2*x2 <= 12.
Stelios
  • 5,271
  • 1
  • 18
  • 32
  • 5
    Couldnt get the sign parameter to work. the sign the parameter is not in the link of documentation you posted either. – user1559897 Jan 22 '19 at 15:14
  • 5
    @user1559897 Apparently, the documentation has been updated and the "sign" approach has been dropped, which I think it is appropriate as it is mostly confusing than providing any convenience. Just provide the sign "manually" as part of the objective function output – Stelios Jan 22 '19 at 15:39
  • Can you give an example for that? – shredding Feb 06 '20 at 07:30
  • 2
    @shredding maximization of a function `f` is equivalent to minimization of `-f` – Stelios Feb 07 '20 at 03:23
5

If anyone wants the working code, below it is. I have also added with cvx. The solution is x: array([2., 6.])

def objective(x, sign=-1.0):
    x1 = x[0]
    x2 = x[1]
    return sign*(3*x1 + 5*x2)

def constraint1(x):
    return 18.0 - 3*x[0] -2*x[1]

x0 = [0,0]

b1 = (0,4)
b2 = (0,6)
bnds= (b1,b2)
con1 = {'type': 'ineq', 'fun': constraint1}
cons = [con1]
sol = minimize(objective, x0, method='SLSQP', bounds = bnds, constraints = cons)

print(sol)

CVXPY

 # Create two scalar optimization variables (CVXPY Variable)
 x1 = cp.Variable()
 x2 = cp.Variable()
 # Create two constraints (Python list)
 constraints = [3*x1 + 2*x2 <= 18, x1 >= 0, x2 >= 0, x1 <=4, x2 <= 6]
 # Form objective
 obj = cp.Maximize(3*x1 + 5*x2)
 # Form and solve problem
 prob = cp.Problem(obj, constraints)
 prob.solve() # Returns the optimal value.
 print("status:", prob.status)
 print("optimal value", np.round(prob.value, 5))
 print("optimal var", np.round(x1.value, 5), np.round(x2.value, 5))
Fisseha Berhane
  • 2,533
  • 4
  • 30
  • 48