scipy.optimize.shgo¶
- scipy.optimize.shgo(func, bounds, args=(), constraints=None, n=None, iters=1, callback=None, minimizer_kwargs=None, options=None, sampling_method='simplicial')[源代码]¶
使用SHG优化查找函数的全局最小值。
SHGO代表“单纯同调全局优化”。
- 参数
- func可调用
要最小化的目标函数。必须在表格中
f(x, *args)
,在哪里x
是一维数组形式的参数,并且args
是完全指定函数所需的任何附加固定参数的元组。- bounds序列
变量的界限。
(min, max)
中每个元素的对x
的优化参数的下界和上界。 func 。它被要求有len(bounds) == len(x)
。len(bounds)
用于确定x
。使用None
对于min或max之一,当在该方向上没有界限时。默认情况下,界限为(None, None)
。- args元组,可选
完全指定目标函数所需的任何附加固定参数。
- constraints判决或判决顺序,可选
约束定义。函数
R**n
在表单中::g(x) >= 0 applied as g : R^n -> R^m h(x) == 0 applied as h : R^n -> R^p
每个约束都在带有字段的字典中定义:
- 类型应力
约束类型:‘EQ’表示相等,‘ineq’表示不平等。
- 有趣的可调用
定义约束的函数。
- JAC可调用,可选
的雅可比 fun (仅适用于SLSQP)。
- 参数序列,可选
要传递给函数和雅可比的额外参数。
等式约束表示约束函数结果为零,而不等式表示约束函数结果为非负。请注意,COBYLA仅支持不等式约束。
注解
目前只有COBYLA和SLSQP局部最小化方法支持约束参数。如果
constraints
在局部优化问题中使用的序列未在中定义minimizer_kwargs
并使用约束方法,然后全局constraints
将会被使用。(定义constraints
顺序输入minimizer_kwargs
意味着constraints
将不会添加,因此如果需要添加等式约束等,则constraints
需要添加到minimizer_kwargs
也是如此)。- n整型,可选
在构建单纯复合体时使用的采样点数量。请注意,此参数仅用于
sobol
以及其他武断的 sampling_methods 。如果sobol
,它必须是2的幂:n=2**m
,参数将自动转换为2的下一个更高的幂。sampling_method='simplicial'
和128个用于sampling_method='sobol'
。- iters整型,可选
构造单纯复形时使用的迭代次数。默认值为1。
- callback可调用,可选
在每次迭代后调用,如
callback(xk)
,在哪里xk
是当前参数向量。- minimizer_kwargsDICT,可选
要传递给最小化程序的额外关键字参数
scipy.optimize.minimize
一些重要选项可能包括:- 方法应力
最小化方法,默认值为
SLSQP
。
- 参数元组
传递给目标函数的额外参数 (
func
)及其导数(雅可比、黑森)。
- 选项DICT,可选
请注意,默认情况下,容差指定为
{{ftol: 1e-12}}
- optionsDICT,可选
求解器选项词典。为全局例程指定的许多选项也会传递给scipy.Optimize.Minimize例程。也传递给本地例程的选项用“(L)”标记。
停止条件时,如果满足任何指定的条件,则算法将终止。但是,默认算法不需要指定任何内容:
- MAXFEVINT(L)
可行域中函数求值的最大次数。(请注意,只有支持此选项的方法才会在精确的指定值终止例程。否则,标准将仅在全局迭代期间终止)
- f_min
指定最小目标函数值(如果已知)。
- f_tol浮动
停止准则中f的值的精度目标。请注意,如果全局例程中的采样点在该容差内,则全局例程也将终止。
- 最大值集成
要执行的最大迭代次数。
- MAXEV集成
要执行的最大抽样评估次数(包括在不可行点中搜索)。
- 最大时间浮动
允许的最大处理运行时间
- 明格勒集成
最小同调群秩微分。在每次迭代期间(近似地)计算目标函数的同调群。该组的秩与目标函数中的局部凸子域的数目具有一一对应关系(在足够的采样点之后,每个子域包含唯一的全局最小值)。如果HGR中的差值在以下两次迭代之间为0
maxhgrd
指定的迭代算法将终止。
目标函数知识:
- 对称性布尔尔
如果目标函数包含对称变量,请指定True。搜索空间(因此性能)减少了O(n!)。
- JACBool或Callable,可选
目标函数的雅可比(梯度)。仅适用于CG、BFGS、Newton-CG、L-BFGS-B、TNC、SLSQP、Dogleg、TRUST-NCG。如果
jac
是布尔值并且为True,fun
假定随目标函数一起返回梯度。如果为False,则将以数值方式估计渐变。jac
也可以是返回目标渐变的可调用函数。在这种情况下,它必须接受与fun
。(传递给 scipy.optimize.minmize 自动)
- 赫斯,赫斯普可调用,可选
目标函数的Hessian(二阶导数矩阵)或目标函数的Hessian乘以任意向量p。仅适用于牛顿-CG、狗腿、TRUST-NCG。只有一个
hessp
或hess
需要给予。如果hess
被提供,则hessp
将被忽略。如果两者都不是hess
也不是hessp
,则将使用有限差分来近似黑森乘积。jac
。hessp
必须计算黑森乘以任意向量。(传递给 scipy.optimize.minmize 自动)
算法设置:
- minimize_every_iter布尔尔
如果为True,则有希望的全局采样点将在每次迭代中传递到局部最小化例程。如果为False,则只会运行最终的最小化器池。默认为False。
- local_iter集成
每次迭代只评估几个最好的极小化池候选者。如果为假,则将所有潜在点传给局部最小化例程。
- INFTY_CONSTRAINTS:布尔值
如果为True,则将保存在可行域之外生成的任何采样点,并为其指定目标函数值
inf
。如果为假,则这些点将被丢弃。使用此功能可以在找到全局最小值之前提高函数求值的性能,指定False将使用更少的内存,但会略微降低性能。默认为True。
反馈:
- 显示布尔值(L)
设置为True可打印收敛消息。
- sampling_method字符串或函数,可选
当前内置采样方法选项包括
halton
,sobol
和simplicial
。默认设置simplicial
为在有限时间内收敛到全局最小值提供了理论保证。halton
和sobol
该方法在采样点生成方面速度更快,但代价是失去了保证的收敛性。它更适合于收敛速度相对较快的大多数“较容易”的问题。用户定义的采样函数必须接受以下两个参数n
尺寸的采样点dim
每个调用,并输出具有形状的采样点数组 n x dim 。
- 退货
- resOptimizeResult
优化结果表示为
OptimizeResult
对象。重要属性包括:x
该解阵列对应于全局最小值,fun
在全局解处输出的函数,xl
局部极小解的有序列表,funl
该函数在相应的局部解处输出,success
指示优化器是否成功退出的布尔标志,message
其描述了终止的原因,nfev
包括采样调用的目标函数评估的总数,nlfev
最终来自所有局部搜索优化的目标函数评估的总数,nit
全局例程执行的迭代次数。
注意事项
单纯形同调全局优化的全局优化 [1]. 适用于解决一般用途的NLP和黑盒优化问题到全局最优(低维问题)。
一般而言,优化问题的形式为::
minimize f(x) subject to g_i(x) >= 0, i = 1,...,m h_j(x) = 0, j = 1,...,p
其中x是一个或多个变量的向量。
f(x)
是目标函数R^n -> R
,g_i(x)
是不等式约束,并且h_j(x)
是相等约束。或者,x中每个元素的下界和上界也可以使用 bounds 论点。
虽然SHGO的大多数理论优势仅在以下情况下得到证明
f(x)
是Lipschitz光滑函数时,对于更一般的情形,也证明了算法收敛到全局最优值f(x)
如果使用默认采样方法,则为非连续、非凸和非平滑 [1].本地搜索方法可以使用
minimizer_kwargs
传递给的参数scipy.optimize.minimize
。默认情况下,SLSQP
方法。通常,建议使用SLSQP
或COBYLA
如果为问题定义了不等式约束,则局部最小化,因为其他方法不使用约束。这个
halton
和sobol
方法点是使用以下工具生成的scipy.stats.qmc
。可以使用任何其他的QMC方法。参考文献
- 1(1,2)
Endres,SC,Sandrock,C,Focke,WW(2018)“用于Lipschitz优化的单纯同源算法”,“全球优化杂志”。
- 2
Joe,SW和Kuo,FY(2008)“用更好的二维投影构造Sobol‘序列”,SIAM J.Sci。电脑。30,2635-2654。
- 3(1,2)
Hoch,W,Schittkowski,K(1981),“非线性规划代码的测试实例”,“经济学与数学系统讲稿”,187。斯普林格-维拉格,纽约。http://www.ai7.uni-bayreuth.de/test_problem_coll.pdf
- 4
Wales,DJ(2015)“视角:从势能景观洞察反应坐标和动力学”,“化学物理杂志”,第142期(13),2015年。
示例
首先考虑最小化Rosenbrock函数的问题,
rosen
:>>> from scipy.optimize import rosen, shgo >>> bounds = [(0,2), (0, 2), (0, 2), (0, 2), (0, 2)] >>> result = shgo(rosen, bounds) >>> result.x, result.fun (array([1., 1., 1., 1., 1.]), 2.920392374190081e-18)
请注意,界限确定目标函数的维数,因此是必需的输入,但是您可以使用
None
或者像这样的对象np.inf
它将被转换为大的浮点数。>>> bounds = [(None, None), ]*4 >>> result = shgo(rosen, bounds) >>> result.x array([0.99999851, 0.99999704, 0.99999411, 0.9999882 ])
接下来,我们考虑Egghold函数,这是一个具有多个局部最小值和一个全局最小值的问题。我们将演示参数的使用以及
shgo
。(https://en.wikipedia.org/wiki/Test_functions_for_optimization)>>> def eggholder(x): ... return (-(x[1] + 47.0) ... * np.sin(np.sqrt(abs(x[0]/2.0 + (x[1] + 47.0)))) ... - x[0] * np.sin(np.sqrt(abs(x[0] - (x[1] + 47.0)))) ... ) ... >>> bounds = [(-512, 512), (-512, 512)]
shgo
具有内置的低偏差采样序列。首先,我们将输入64个初始采样点 苏博尔的 顺序:>>> result = shgo(eggholder, bounds, n=64, sampling_method='sobol') >>> result.x, result.fun (array([512. , 404.23180824]), -959.6406627208397)
shgo
对于找到的任何其他局部最小值,也有一个返回值,可以使用以下命令调用这些函数:>>> result.xl array([[ 512. , 404.23180824], [ 283.0759062 , -487.12565635], [-294.66820039, -462.01964031], [-105.87688911, 423.15323845], [-242.97926 , 274.38030925], [-506.25823477, 6.3131022 ], [-408.71980731, -156.10116949], [ 150.23207937, 301.31376595], [ 91.00920901, -391.283763 ], [ 202.89662724, -269.38043241], [ 361.66623976, -106.96493868], [-219.40612786, -244.06020508]])
>>> result.funl array([-959.64066272, -718.16745962, -704.80659592, -565.99778097, -559.78685655, -557.36868733, -507.87385942, -493.9605115 , -426.48799655, -421.15571437, -419.31194957, -410.98477763])
这些结果在存在许多全局最小值并且期望其他全局最小值的值的应用中或者在局部最小值可以提供对系统的洞察(例如物理化学中的形态学)的应用中是有用的 [4]) 。
如果我们想要找到更多的局部极小值,可以增加采样点的数量或迭代的次数。我们将采样点的数量增加到64,迭代次数从默认值1增加到3。
simplicial
这将为我们提供64x3=192个初始采样点。>>> result_2 = shgo(eggholder, bounds, n=64, iters=3, sampling_method='sobol') >>> len(result.xl), len(result_2.xl) (12, 20)
注意以下不同之处,例如,
n=192, iters=1
和n=64, iters=3
。在第一种情况下,包含在最小化池中的有希望的点只被处理一次。在后一种情况下,每64个采样点处理一次,总共处理3次。为了演示如何解决具有非线性约束的问题,请考虑Hock和Schittkowski问题73(牛饲料)中的以下示例 [3]:
minimize: f = 24.55 * x_1 + 26.75 * x_2 + 39 * x_3 + 40.50 * x_4 subject to: 2.3 * x_1 + 5.6 * x_2 + 11.1 * x_3 + 1.3 * x_4 - 5 >= 0, 12 * x_1 + 11.9 * x_2 + 41.8 * x_3 + 52.1 * x_4 - 21 -1.645 * sqrt(0.28 * x_1**2 + 0.19 * x_2**2 + 20.5 * x_3**2 + 0.62 * x_4**2) >= 0, x_1 + x_2 + x_3 + x_4 - 1 == 0, 1 >= x_i >= 0 for all i
中给出的近似答案 [3] 是::
f([0.6355216, -0.12e-11, 0.3127019, 0.05177655]) = 29.894378
>>> def f(x): # (cattle-feed) ... return 24.55*x[0] + 26.75*x[1] + 39*x[2] + 40.50*x[3] ... >>> def g1(x): ... return 2.3*x[0] + 5.6*x[1] + 11.1*x[2] + 1.3*x[3] - 5 # >=0 ... >>> def g2(x): ... return (12*x[0] + 11.9*x[1] +41.8*x[2] + 52.1*x[3] - 21 ... - 1.645 * np.sqrt(0.28*x[0]**2 + 0.19*x[1]**2 ... + 20.5*x[2]**2 + 0.62*x[3]**2) ... ) # >=0 ... >>> def h1(x): ... return x[0] + x[1] + x[2] + x[3] - 1 # == 0 ... >>> cons = ({'type': 'ineq', 'fun': g1}, ... {'type': 'ineq', 'fun': g2}, ... {'type': 'eq', 'fun': h1}) >>> bounds = [(0, 1.0),]*4 >>> res = shgo(f, bounds, iters=3, constraints=cons) >>> res fun: 29.894378159142136 funl: array([29.89437816]) message: 'Optimization terminated successfully.' nfev: 114 nit: 3 nlfev: 35 nlhev: 0 nljev: 5 success: True x: array([6.35521569e-01, 1.13700270e-13, 3.12701881e-01, 5.17765506e-02]) xl: array([[6.35521569e-01, 1.13700270e-13, 3.12701881e-01, 5.17765506e-02]])
>>> g1(res.x), g2(res.x), h1(res.x) (-5.062616992290714e-14, -2.9594104944408173e-12, 0.0)