我們要求解的最優化問題的形式如下:
m i n ? f ( x ) s . t . g i ( x ) > 0 , i = 1 , . . . , m h j ( x ) = 0 , j = 1 , . . . , n \begin{aligned} min \ f(x) \\ s.t.\quad g_i(x)& \gt 0, i = 1,...,m\\ \quad h_j(x)& = 0, j = 1,...,n \end{aligned}
m
i
n
?
f
(
x
)
s
.
t
.
g
i
?
(
x
)
h
j
?
(
x
)
?
>
0
,
i
=
1
,
.
.
.
,
m
=
0
,
j
=
1
,
.
.
.
,
n
?
其中
x x
x
是一個向量,
g i ( x ) g_i(x)
g
i
?
(
x
)
是非等式約束,
h j ( x ) h_j(x)
h
j
?
(
x
)
是等式約束。
示例
在 x , y , z > 0 , x y z = 1 x,y,z>0,xyz=1 x , y , z > 0 , x y z = 1 的條件下,求解 ( x ? 2 / 3 ) / ( x + y + z ? 2 ) (x-2/3)/(x+y+z-2) ( x ? 2 / 3 ) / ( x + y + z ? 2 ) 的最小值。
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
的約束是表示非負,所以 x > 0 x>0 x > 0 的條件可以寫為 x ? e ≥ 0 x-e\ge0 x ? e ≥ 0 ,其中 e e e 是一個盡可能小的值。 - 其實,在本題中,可以直接讓 x > 0 x\gt0 x > 0 ,因為有約束 x y z = 1 xyz=1 x y z = 1 ,所以不必擔心最后解為 x = 0 x=0 x = 0 。
函數介紹
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
。當約束是針對 x x x 中的單個元素的上下限時,就可以用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
描述了求解器退出的原因。
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
