首先将优化目标写成如图一所示的形式(在 SciPy 中,要将不等约束写成大于的形式)
图一
然后导入包
import numpy as np
import scipy.optimize as opt
基本形式为
opt.minimize(目标函数, 初始值, constraints=约束条件, bounds=约束边界, jac=雅可比函数, ...)
除了前两个条件外,后面的都可以省略。
举个例子,求解如下目标函数的最小值
约束条件为
可以用如下代码
# 目标函数
def func(x, sign=1.0):
""" Objective function """
return sign*(2*x[0]*x[1] + 2*x[0] - x[0]**2 - 2*x[1]**2)
# 目标函数的导函数
def func_deriv(x, sign=1.0):
""" Derivative of objective function """
dfdx0 = sign*(-2*x[0] + 2*x[1] + 2)
dfdx1 = sign*(2*x[0] - 4*x[1])
return np.array([ dfdx0, dfdx1 ])
# 约束条件
cons = ({'type': 'eq',
'fun' : lambda x: np.array([x[0]**3 - x[1]]),
'jac' : lambda x: np.array([3.0*(x[0]**2.0), -1.0])},
{'type': 'ineq',
'fun' : lambda x: np.array([x[1] - 1]),
'jac' : lambda x: np.array([0.0, 1.0])})
>>> res = minimize(func, [-1.0,1.0], args=(-1.0,), jac=func_deriv,
... method='SLSQP', options={'disp': True})
Optimization terminated successfully. (Exit mode 0)
Current function value: -2.0
Iterations: 4 # may vary
Function evaluations: 5
Gradient evaluations: 4
>>> res
fun: -2.0
jac: array([-0., -0.])
message: 'Optimization terminated successfully.'
nfev: 5
nit: 4
njev: 4
status: 0
success: True
x: array([ 2., 1.])
>>> print(res.x)
[ 2. 1.]
当然,在导函数未知的情况下,也可以不写,但这样可能会影响速度和精度。
# 约束条件
cons = ({'type': 'eq',
'fun' : lambda x: np.array([x[0]**3 - x[1]]),},
{'type': 'ineq',
'fun' : lambda x: np.array([x[1] - 1]),})
res = opt.minimize(func, [-1.0,1.0], args=(-1.0,),
method='SLSQP', options={'disp': True})
网友评论