我們要求解的最優化問題的形式如下:
其中 是一個向量, 是非等式約束, 是等式約束。
示例
在 的條件下,求解 的最小值。
from scipy.optimize import minimize
import numpy as np
e = 1e-10 # 非常接近0的值
fun = lambda x : (x[0] - 0.667) / (x[0] + x[1] + x[2] - 2) # 約束函數
cons = ({'type': 'eq', 'fun': lambda x: x[0] * x[1] * x[2] - 1}, # xyz=1
{'type': 'ineq', 'fun': lambda x: x[0] - e}, # x>=e,即 x > 0
{'type': 'ineq', 'fun': lambda x: x[1] - e},
{'type': 'ineq', 'fun': lambda x: x[2] - e}
)
x0 = np.array((1.0, 1.0, 1.0)) # 設置初始值
res = minimize(fun, x0, method='SLSQP', constraints=cons)
print('最小值:',res.fun)
print('最優解:',res.x)
print('迭代終止是否成功:', res.success)
print('迭代終止原因:', res.message)
輸出:
最小值: -0.18814357989751096
最優解: [0.29250894 1.84897232 1.84897233]
迭代終止是否成功: True
迭代終止原因: Optimization terminated successfully.
備註:
- 若是求一個函數的最大值,則改爲求其相反數的最小值。
- 因爲
ineq
的約束是表示非負,所以 的條件可以寫爲 ,其中是一個儘可能小的值。 - 其實,在本題中,可以直接讓 ,因爲有約束 ,所以不必擔心最後解爲 。
函數介紹
scipy.optimize.minimize(fun, x0, args=(), method=None, jac=None, hess=None, hessp=None, bounds=None, constraints=(), tol=None, callback=None, options=None)
求取一個函數的最小值。函數的參數可以是多個,但函數值只能是標量。
參數
- fun : callable
目標函數 - x0 : ndarry
初始值 - args : tuple, optional
額外的參數,傳給目標函數和它的導數。 - method : str or callable, optional
求解問題的算法名,下面選其一:
Nelder-Mead
,Powell
,CG
,BFGS
,Newton-CG
,L-BFGS-B
,TNC
,COBYLA
,SLSQP
,dogleg
,trust-ncg
默認是BFGS
,L-BFGS-B
,SLSQP
之一,根據問題是否含有約束和界限自動選擇。 - jac : bool or callable, optional
目標函數的梯度矩陣。只適用於CG
,BFGS
,Newton-CG
,L-BFGS-B
,TNC
,SLSQP
,dogleg
,trust-ncg
。如果jac
是一個Boolean
且爲True
,則fun
被認爲是梯度與目標函數一起返回。如果是False
,則梯度會被自動地計算。jac
也可以是一個函數,返回目標函數的梯度,且參數必須與fun
相同。 - hess, hessp : callable, optional
目標函數的二階導矩陣,或者二階導矩陣乘以一個隨機向量p
。只適用於Newton-CG
,dogleg
,trust-ncg
。hess
和hessp
只需要給出一個即可。如果提供了hess
,則hessp
會被忽略。如果兩者都沒有提供,則二階導矩陣會被自動計算。 - bounds : sequence, optional
bounds
是參數的界限,只適用於L-BFGS-B
,TNC
和SLSQP
,每個參數對應一個(min, max)
,表示參數的上下限。如果只有一邊界限,則另一邊置爲None
。當約束是針對 中的單個元素的上下限時,就可以用bounds
參數來設置。 - constraints : dict or sequence of dict, optional
約束定義,只適用於COBYLA
和SLSQP
。每個約束定義爲一個詞典,鍵值對包括:- fun : callable。定義了約束函數。
- type : str。約束類型:
eq
’ 表示等式約束(fun
等於0),ineq
表示不等式約束(fun
大於等於0)。COBYLA
只支持不等式約束。 - jac : callable, optional。
fun
的梯度矩陣,只適用於SLSQP
- args : sequence, optional。傳遞給
fun
和jac
的額外參數。
- tol : float, optional
迭代終止的允許誤差。 - options : dict, optional
求解器的選項字典。所有的算法都接受以下的通用選項:- maxiter : int。迭代的最大次數。
- disp : bool。如果是
True
則打印出收斂信息。
- callback : callable, optional
每次迭代之後調用的函數,參數爲xk
,表示當前的參數向量。
返回值
res:優化結果。
優化結果是OptimizeResult
對象,重要屬性如下:
fun
是最優值。x
是最優解。success
表示求解器是否成功退出。message
描述了求解器退出的原因。