dual_annealing#
- scipy.optimize.dual_annealing(func, bounds, args=(), maxiter=1000, minimizer_kwargs=None, initial_temp=5230.0, restart_temp_ratio=2e-05, visit=2.62, accept=-5.0, maxfun=10000000.0, rng=None, no_local_search=False, callback=None, x0=None)[原始碼]#
使用雙重退火法尋找函數的全域最小值。
- 參數:
- funccallable
要最小化的目標函數。 必須採用
f(x, *args)
的形式,其中x
是 1 維陣列形式的引數,而args
是一個元組,包含完全指定函數所需的任何其他固定參數。- boundssequence 或
Bounds
變數的界限。 有兩種方法可以指定界限
Bounds
類別的實例。每個 x 元素的
(min, max)
配對序列。
- argstuple,選用
完全指定目標函數所需的任何其他固定參數。
- maxiterint,選用
全域搜尋迭代的最大次數。 預設值為 1000。
- minimizer_kwargsdict,選用
要傳遞給局部最小化器 (
minimize
) 的關鍵字引數。 一個重要的選項可能是要使用的最小化器方法的method
。 如果未提供關鍵字引數,則局部最小化器預設為 ‘L-BFGS-B’,並使用已提供的界限。 如果指定了 minimizer_kwargs,則 dict 必須包含控制局部最小化所需的所有參數。 args 在此 dict 中會被忽略,因為它會自動傳遞。 bounds 不會自動傳遞給局部最小化器,因為該方法可能不支援它們。- initial_tempfloat,選用
初始溫度,使用較高的值有助於更廣泛地搜尋能量景觀,使 dual_annealing 能夠逃脫其陷入的局部最小值。 預設值為 5230。 範圍為 (0.01, 5.e4]。
- restart_temp_ratiofloat,選用
在退火過程中,溫度會降低,當溫度達到
initial_temp * restart_temp_ratio
時,會觸發重新退火過程。 比率的預設值為 2e-5。 範圍為 (0, 1)。- visitfloat,選用
訪問分佈的參數。 預設值為 2.62。 較高的值會使訪問分佈具有更重的尾部,這會使演算法跳到更遠的區域。 值範圍為 (1, 3]。
- acceptfloat,選用
接受分佈的參數。 它用於控制接受的機率。 接受參數越低,接受的機率越小。 預設值為 -5.0,範圍為 (-1e4, -5]。
- maxfunint,選用
目標函數呼叫次數的軟限制。 如果演算法正處於局部搜尋的中間,則此數字將會被超過,演算法將在局部搜尋完成後立即停止。 預設值為 1e7。
- rng{None, int,
numpy.random.Generator
},選用 如果透過關鍵字傳遞 rng,則除了
numpy.random.Generator
以外的類型會傳遞給numpy.random.default_rng
以實例化Generator
。 如果 rng 已經是Generator
實例,則會使用提供的實例。 指定 rng 以獲得可重複的函數行為。如果此引數是透過位置傳遞,或 seed 是透過關鍵字傳遞,則引數 seed 的舊版行為適用
如果 seed 為 None (或
numpy.random
),則會使用numpy.random.RandomState
singleton。如果 seed 是整數,則會使用新的
RandomState
實例,並以 seed 作為種子。如果 seed 已經是
Generator
或RandomState
實例,則會使用該實例。
在 1.15.0 版本中變更: 作為從使用
numpy.random.RandomState
過渡到numpy.random.Generator
的 SPEC-007 過渡的一部分,此關鍵字已從 seed 變更為 rng。 在過渡期間,這兩個關鍵字將繼續運作,但一次只能指定一個。 在過渡期之後,使用 seed 關鍵字的函數呼叫將發出警告。 seed 和 rng 的行為都已在上面概述,但在新程式碼中應僅使用 rng 關鍵字。指定 rng 以獲得可重複的最小化。 產生的隨機數僅影響訪問分佈函數和新座標生成。
- no_local_searchbool,選用
如果 no_local_search 設定為 True,則將執行傳統的廣義模擬退火法,而不應用局部搜尋策略。
- callbackcallable,選用
簽名為
callback(x, f, context)
的回呼函數,將為找到的所有最小值呼叫此函數。x
和f
是最新找到的最小值的座標和函數值,而context
具有以下值之一0
:在退火過程中偵測到最小值。1
:在局部搜尋過程中發生偵測。2
:在雙重退火過程中完成偵測。
如果回呼實作傳回 True,則演算法將停止。
- x0ndarray,形狀(n,),選用
單個 N 維起點的座標。
- 傳回:
- resOptimizeResult
最佳化結果,表示為
OptimizeResult
物件。 重要的屬性包括:x
解答陣列、fun
解答處的函數值,以及message
描述終止原因的訊息。 有關其他屬性的說明,請參閱OptimizeResult
。
註解
此函數實作雙重退火最佳化。 這種隨機方法源自 [3],結合了 CSA (傳統模擬退火法) 和 FSA (快速模擬退火法) 的廣義化 [1] [2],並結合了將局部搜尋應用於接受位置的策略 [4]。 [5] 中描述了同一演算法的替代實作,[6] 中提供了基準測試。 這種方法引入了一種先進的方法來改進廣義退火過程找到的解。 此演算法使用扭曲的柯西-洛倫茲訪問分佈,其形狀由參數 \(q_{v}\) 控制
\[g_{q_{v}}(\Delta x(t)) \propto \frac{ \ \left[T_{q_{v}}(t) \right]^{-\frac{D}{3-q_{v}}}}{ \ \left[{1+(q_{v}-1)\frac{(\Delta x(t))^{2}} { \ \left[T_{q_{v}}(t)\right]^{\frac{2}{3-q_{v}}}}}\right]^{ \ \frac{1}{q_{v}-1}+\frac{D-1}{2}}}\]其中 \(t\) 是人工時間。 此訪問分佈用於產生變數 \(x(t)\) 在人工溫度 \(T_{q_{v}}(t)\) 下的試驗跳躍距離 \(\Delta x(t)\)。
從起點開始,在呼叫訪問分佈函數後,接受機率計算如下
\[p_{q_{a}} = \min{\{1,\left[1-(1-q_{a}) \beta \Delta E \right]^{ \ \frac{1}{1-q_{a}}}\}}\]其中 \(q_{a}\) 是接受參數。 對於 \(q_{a}<1\),零接受機率被分配給以下情況
\[[1-(1-q_{a}) \beta \Delta E] < 0\]人工溫度 \(T_{q_{v}}(t)\) 根據以下公式降低
\[T_{q_{v}}(t) = T_{q_{v}}(1) \frac{2^{q_{v}-1}-1}{\left( \ 1 + t\right)^{q_{v}-1}-1}\]其中 \(q_{v}\) 是訪問參數。
在 1.2.0 版本中新增。
參考文獻
[1]Tsallis C. Possible generalization of Boltzmann-Gibbs statistics. Journal of Statistical Physics, 52, 479-487 (1998).
[2]Tsallis C, Stariolo DA. Generalized Simulated Annealing. Physica A, 233, 395-406 (1996).
[3]Xiang Y, Sun DY, Fan W, Gong XG. Generalized Simulated Annealing Algorithm and Its Application to the Thomson Model. Physics Letters A, 233, 216-220 (1997).
[4]Xiang Y, Gong XG. Efficiency of Generalized Simulated Annealing. Physical Review E, 62, 4473 (2000).
[5]Xiang Y, Gubian S, Suomela B, Hoeng J. Generalized Simulated Annealing for Efficient Global Optimization: the GenSA Package for R. The R Journal, Volume 5/1 (2013).
[6]Mullen, K. Continuous Global Optimization in R. Journal of Statistical Software, 60(6), 1 - 45, (2014). DOI:10.18637/jss.v060.i06
範例
以下範例是一個 10 維問題,具有許多局部最小值。 涉及的函數稱為 Rastrigin (https://en.wikipedia.org/wiki/Rastrigin_function)
>>> import numpy as np >>> from scipy.optimize import dual_annealing >>> func = lambda x: np.sum(x*x - 10*np.cos(2*np.pi*x)) + 10*np.size(x) >>> lw = [-5.12] * 10 >>> up = [5.12] * 10 >>> ret = dual_annealing(func, bounds=list(zip(lw, up))) >>> ret.x array([-4.26437714e-09, -3.91699361e-09, -1.86149218e-09, -3.97165720e-09, -6.29151648e-09, -6.53145322e-09, -3.93616815e-09, -6.55623025e-09, -6.05775280e-09, -5.00668935e-09]) # random >>> ret.fun 0.000000