我尝试复制this简单优化问题,以便开始使用Scipy.optimize。 问题是一个典型的产品组合问题,其目标是在一些生产和配料限制的情况下实现利润最大化,在这种情况下,它是一家拥有三种咖啡类型的咖啡店。
约束:
目标函数
这是我的代码(请注意我在笔记本中运行):
from scipy.optimize import minimize
#profit / cup
Reg = 1.25
Lat = 2.00
Moc = 2.25
#objective function to maximize
def objective(x):
return (x[0]*Reg + x[1]*Lat + x[2]*Moc)
#constraints
def cons_total_production(x):
return (sum(x))-500
def cons_choc(x):
return (x[2])-125
def cons_milk(x):
return (sum(x[1:]))-350
cons1 = {'type':'ineq', 'fun':cons_total_production}
cons2 = {'type':'ineq', 'fun':cons_choc}
cons3 = {'type':'ineq', 'fun':cons_milk}
cons = [cons1,cons2,cons3]
#boundries
bnds = ((0,None),(0,None),(0,None))
#initial guess
x0 = [250,150,100]
#let scipy do its magic
sol = minimize(objective, x0, constraints=cons, bounds=bnds)
这会产生正确的输出。 当我使用scipy最小化时,这怎么可能?
fun: 918.7499999999358
jac: array([ 1.25, 2. , 2.25])
message: 'Optimization terminated successfully.'
nfev: 50
nit: 10
njev: 10
status: 0
success: True
x: array([ 150., 225., 125.])
但是当我尝试添加一个约束时,输出是错误的。例如,如果我做一个约束声明x0必须等于x1,我会更改以下内容并再次运行模型:
def cons_eq(x):
return x[0]-x[1]
cons4 = {'type':'eq', 'fun':cons_eq}
cons = [cons1, cons2, cons3, cons4]
但是现在我的约束x2< = 125被忽略了:
fun: 937.4999999999934
jac: array([ 1.25, 2. , 2.25])
message: 'Optimization terminated successfully.'
nfev: 35
nit: 7
njev: 7
status: 0
success: True
x: array([ 150., 150., 200.])
有什么建议吗? thx ...
答案 0 :(得分:2)
问题在于你的目标函数和约束。由于您使用scipy的最小化功能,您必须最小化目标函数的负数以找到函数的最大值(这有点棘手)。< / p>
#objective function to maximize
def objective(x):
return -1.0*(x[0]*Reg + x[1]*Lat + x[2]*Moc)
您还错误地输入了不等式函数。如果你查看scipy文档,所有不等式都是g(x)&gt; = 0的形式。因此,例如,如果你想要x2&lt; = 125,你必须乘以负1(以切换不等式),然后加125得到:g(x)= 125-x2&gt; = 0.所以其余的你的约束:
#constraints
def cons_total_production(x):
return (-1.0*sum(x))+500
def cons_choc(x):
return (-1.0*x[2])+125
def cons_milk(x):
return (-1.0*sum(x[1:]))+350
这将为您提供输出:
fun: -918.7499999999989
jac: array([-1.25, -2. , -2.25])
message: 'Optimization terminated successfully.'
nfev: 35
nit: 7
njev: 7
status: 0
success: True
x: array([ 150., 225., 125.])
fun: -890.62499998809
jac: array([-1.25, -2. , -2.25])
message: 'Optimization terminated successfully.'
nfev: 10
nit: 2
njev: 2
status: 0
success: True
x: array([ 187.5, 187.5, 125. ])
线性编程非常酷!
希望有所帮助:)