圖書序言
主題3. 最佳化演算(Optimization) 求極值
前面的主題是解滿足一階導函數的根,因此,我們必須先微分求出導函數。但是,最簡單的方法是直接對目標函數求解:同時解出目標極值和臨界值。
Python完成這件事有sympy和scipy,筆者覺得sympy需要宣告的參數太多,尤其是在帶限制式時。所以我們使用模組scipy內的函數optimize()和minimize(),Python程式碼的步驟解說如下。
5.3-1 單變數
我們先看本章範例1的簡單方程式,如下:
第1步:定義函數
from scipy import optimize
def f(x, sign=-1):
return sign*(2*x**3+3*x**2-12*x-7)
兩行就OK,相當簡易。待會我們再解釋sign的意義。接下來執行求極值:
第2步:求解與結果
Result1 = optimize. minimize_scalar(f)
Result1.x
Result1.fun
f(Result1.x)
optimize. minimize_scalar()是求解函數。Result1內有許多物件,主要有三個:
(1) Result1.x: 解出的x值。
(2) Result1.fun: 解出的極小值,可以和f(Result1.x)對照是否一樣。
(3) Result1.success: 回傳求解是否成功(True/False)。
我們看看列印在螢幕的結果,如下:
Result1.x
Out[2]: 1.0
Result1.fun
Out[3]: -14.0
f(Result1.x)
Out[4]: -14.0
我們回去看範例1的圖形,可能的臨界值有兩個,從圖形看的出來,我們解出的只是極小值(1, -14)。那另一極大值的解呢?根據scipy說明文件,須把函數取負值 ,這也是我們為什麼寫函數時,要增加一個參數 sign,因為這樣比較方便,判斷極大值時,可以如下這樣處理:
第1步:定義函數
def f(x, sign = -1):
return sign*(2*x**3+3*x**2-12*x-7)