Scipy 最小化约束函数
Scipy minimize constrained function
我正在解决以下优化问题:
使用此 Python 代码:
from scipy.optimize import minimize
import math
def f(x):
return math.log(x[0]**2 + 1) + x[1]**4 + x[0]*x[2]
x0 = [0, 0, 0]
cons=({'type': 'ineq',
'fun': lambda x: x[0]**3 - x[1]**2 - 1},
{'type': 'ineq',
'fun': lambda x: x[0]},
{'type': 'ineq',
'fun': lambda x: x[2]})
res = minimize(f, x0, constraints=cons)
print res
我收到一个错误
message: 'Inequality constraints incompatible'
什么会导致此错误?
问题似乎出在您最初的猜测上。如果我将您的起始值更改为
x0 = [1.0, 1.0, 1.0]
然后你的代码将执行良好(至少在我的机器上)
Python 3.5.1 (v3.5.1:37a07cee5969, Dec 6 2015, 01:54:25) [MSC v.1900 64 bit (AMD64)] on win32
message: 'Optimization terminated successfully.'
njev: 10
jac: array([ 1., 0., 1., 0.])
fun: 0.6931471805582502
nit: 10
status: 0
x: array([ 1.00000000e+00, -1.39724765e-06, 1.07686548e-14])
success: True
nfev: 51
Scipy 的优化模块有很多选项。参见 the documentation or this tutorial。由于您未在此处指定方法,因此它将使用顺序最小二乘法编程 (SLSQP
)。或者,您可以使用信任域约束算法 (trust-const
).
对于这个问题,我发现 trust-const
似乎比 SLSQP
对起始值更稳健,处理从 [-2,-2,-2]
到 [10,10,10]
的起始值,尽管初始值为负如您所料,值会导致迭代次数增加。 -2
以下的负值超过了最大迭代次数,尽管我怀疑如果你增加最大迭代次数可能仍会收敛,当然,为 x1
和 x3
指定负值有点愚蠢,我这样做只是为了了解它对一系列起始值的鲁棒性。
SLSQP
和 trust-const
的规范在概念上是相同的,但语法略有不同(特别注意 NonlinearConstraint
的用法)。
from scipy.optimize import minimize, NonlinearConstraint, SR1
def f(x):
return math.log(x[0]**2 + 1) + x[1]**4 + x[0]*x[2]
constr_func = lambda x: np.array( [ x[0]**3 - x[1]**2 - 1,
x[0],
x[2] ] )
x0=[0.,0.,0.]
nonlin_con = NonlinearConstraint( constr_func, 0., np.inf )
res = minimize( f, x0, method='trust-constr',
jac='2-point', hess=SR1(),
constraints = nonlin_con )
以下是结果,为简洁起见进行了编辑:
fun: 0.6931502233468916
message: '`gtol` termination condition is satisfied.'
x: array([1.00000063e+00, 8.21427026e-09, 2.40956900e-06])
请注意,函数值和 x 值与@CoryKramer 的回答相同。乍一看 x 数组可能在表面上看起来不同,但两者的答案都是 [1, 0, 0]
.
我正在解决以下优化问题:
使用此 Python 代码:
from scipy.optimize import minimize
import math
def f(x):
return math.log(x[0]**2 + 1) + x[1]**4 + x[0]*x[2]
x0 = [0, 0, 0]
cons=({'type': 'ineq',
'fun': lambda x: x[0]**3 - x[1]**2 - 1},
{'type': 'ineq',
'fun': lambda x: x[0]},
{'type': 'ineq',
'fun': lambda x: x[2]})
res = minimize(f, x0, constraints=cons)
print res
我收到一个错误
message: 'Inequality constraints incompatible'
什么会导致此错误?
问题似乎出在您最初的猜测上。如果我将您的起始值更改为
x0 = [1.0, 1.0, 1.0]
然后你的代码将执行良好(至少在我的机器上)
Python 3.5.1 (v3.5.1:37a07cee5969, Dec 6 2015, 01:54:25) [MSC v.1900 64 bit (AMD64)] on win32
message: 'Optimization terminated successfully.'
njev: 10
jac: array([ 1., 0., 1., 0.])
fun: 0.6931471805582502
nit: 10
status: 0
x: array([ 1.00000000e+00, -1.39724765e-06, 1.07686548e-14])
success: True
nfev: 51
Scipy 的优化模块有很多选项。参见 the documentation or this tutorial。由于您未在此处指定方法,因此它将使用顺序最小二乘法编程 (SLSQP
)。或者,您可以使用信任域约束算法 (trust-const
).
对于这个问题,我发现 trust-const
似乎比 SLSQP
对起始值更稳健,处理从 [-2,-2,-2]
到 [10,10,10]
的起始值,尽管初始值为负如您所料,值会导致迭代次数增加。 -2
以下的负值超过了最大迭代次数,尽管我怀疑如果你增加最大迭代次数可能仍会收敛,当然,为 x1
和 x3
指定负值有点愚蠢,我这样做只是为了了解它对一系列起始值的鲁棒性。
SLSQP
和 trust-const
的规范在概念上是相同的,但语法略有不同(特别注意 NonlinearConstraint
的用法)。
from scipy.optimize import minimize, NonlinearConstraint, SR1
def f(x):
return math.log(x[0]**2 + 1) + x[1]**4 + x[0]*x[2]
constr_func = lambda x: np.array( [ x[0]**3 - x[1]**2 - 1,
x[0],
x[2] ] )
x0=[0.,0.,0.]
nonlin_con = NonlinearConstraint( constr_func, 0., np.inf )
res = minimize( f, x0, method='trust-constr',
jac='2-point', hess=SR1(),
constraints = nonlin_con )
以下是结果,为简洁起见进行了编辑:
fun: 0.6931502233468916
message: '`gtol` termination condition is satisfied.'
x: array([1.00000063e+00, 8.21427026e-09, 2.40956900e-06])
请注意,函数值和 x 值与@CoryKramer 的回答相同。乍一看 x 数组可能在表面上看起来不同,但两者的答案都是 [1, 0, 0]
.