I'm attempting to minimize the function f(x) = x[0] * x[1]
over a system of inequality constraints using scipy.minimize and the solver is returning values which do not respect all of the constraints. For example:
import numpy as np
from scipy.optimize import minimize
from scipy.optimize import fmin_slsqp
# small constant for enforcing strict inequalities
c = 0.000001
# Objective Function to Optimize
def objective(x):
return x[0] * x[1]
# Constraints
def con1(x):
return (x[0]*(1/(7**x[2]))) + 6*x[1] - c
def con2(x):
return (x[0]*(1/(2**x[2]))) + x[1] - c
def con3(x):
return (x[0]*(1/(3**x[2]))) + 2*x[1] - c
def con4(x):
return (x[0]*(1/(4**x[2]))) + 3*x[1] - c
def con5(x):
return (x[0]*(1/(7**x[2]))) - (x[0]*(1/(1**x[2]))) + 7*x[1] - c
def con6(x):
return (x[0]*(1/(2**x[2]))) - (x[0]*(1/(1**x[2]))) + 2*x[1] - c
def con7(x):
return (x[0]*(1/(3**x[2]))) - (x[0]*(1/(1**x[2]))) + 3*x[1] - c
def con8(x):
return -(x[0]*(1/(1**x[2]))) + 4*x[1] - c
def con9(x):
return (x[0]*(1/(1**x[2]))) + 2*x[1] - c
def con10(x):
return (x[0]*(1/(7**x[2]))) + 4*x[1] - c
def con11(x):
return (x[0]*(1/(2**x[2]))) - x[1] - c
def con12(x):
return (x[0]*(1/(4**x[2]))) + x[1] - c
def con13(x):
return x[0] - 1
def con14(x):
return x[1] - 1
def con15(x):
return x[2] - c
# Initial Guesses
x0 = [1,1,1]
# Constraint Objects
constr1 = {'type':'ineq', 'fun':con1}
constr2 = {'type':'ineq', 'fun':con2}
constr3 = {'type':'ineq', 'fun':con3}
constr4 = {'type':'ineq', 'fun':con4}
constr5 = {'type':'ineq', 'fun':con5}
constr6 = {'type':'ineq', 'fun':con6}
constr7 = {'type':'ineq', 'fun':con7}
constr8 = {'type':'ineq', 'fun':con8}
constr9 = {'type':'ineq', 'fun':con9}
constr10 = {'type':'ineq', 'fun':con10}
constr11 = {'type':'ineq', 'fun':con11}
constr12 = {'type':'ineq', 'fun':con12}
constr13 = {'type':'ineq', 'fun':con13}
constr14 = {'type':'ineq', 'fun':con14}
constr15 = {'type':'ineq', 'fun':con15}
cons = [constr1,constr2,constr3,constr4,constr5,constr6,constr7,constr8,constr9,constr10,constr11,constr12,constr13,constr14,constr15]
solution = minimize(objective,x0,method='SLSQP',constraints=cons)
for con in cons:
print(str(con) + str(con['fun'](solution.x)))
Looping over the constraints with the solution values shows that some of the constraints are evaluating as negative even though the constraints are of the form >= 0
.
Is this due to some error on my part in the specifications? An issue with numerical precision? Or is this an issue with SLSQP? (see, for example: https://github.com/scipy/scipy/issues/7618).
If this isn't an issue with my specifications, I would also accept suggestions for formulations of this constraint solving problem in other frameworks (preferably in Python).