scipy.optimize.

直接#

scipy.optimize.direct(func, bounds, *, args=(), eps=0.0001, maxfun=None, maxiter=1000, locally_biased=True, f_min=-inf, f_min_rtol=0.0001, vol_tol=1e-16, len_tol=1e-06, callback=None)[源代码][源代码]#

使用DIRECT算法找到函数的全局最小值。

参数:
函数可调用

要最小化的目标函数。func(x, *args) -> float 其中 x 是一个形状为 (n,) 的 1-D 数组,而 args 是一个包含完全指定函数所需固定参数的元组。

bounds : 序列 或 Bounds序列或

变量的边界。有两种指定边界的方式:

  1. Bounds 类的实例。

  2. x 中每个元素的 (最小值, 最大值) 对。

参数tuple, 可选

完全指定目标函数所需的任何额外固定参数。

epsfloat, 可选

当前最佳超矩形与下一个可能的最优超矩形之间的目标函数值所需的最小差异。因此,eps 作为局部搜索和全局搜索之间的权衡:越小,搜索越局部。默认值为 1e-4。

maxfunint 或 None, 可选

目标函数评估的近似上限。如果为 None,将自动设置为 1000 * N,其中 N 表示维数。如有必要,将限制 DIRECT 的 RAM 使用量约为 1GiB。这仅在维数非常高且 max_fun 过多的情况下发生。默认值为 None

maxiterint, 可选

最大迭代次数。默认值为 1000。

局部偏置bool, 可选

如果 True`(默认),使用称为 DIRECT_L 的局部偏向算法变体。如果 `False,使用原始的无偏 DIRECT 算法。对于有许多局部最小值的难题,建议使用 False

f_minfloat, 可选

全局最优值。仅在已知全局最优值时设置此值。默认值为 -np.inf,因此此终止条件被禁用。

f_min_rtolfloat, 可选

一旦当前最佳最小值 f 与提供的全局最小值 f_min 之间的相对误差小于 f_min_rtol,终止优化。此参数仅在 f_min 也设置时使用。必须在 0 和 1 之间。默认值为 1e-4。

vol_tolfloat, 可选

一旦包含最低函数值的超矩形体积小于完整搜索空间的 vol_tol ,就终止优化。必须介于0和1之间。默认值为1e-16。

len_tolfloat, 可选

如果 locally_biased=True,则在包含最低函数值的超矩形的归一化最大边长的一半小于 len_tol 时终止优化。如果 locally_biased=False,则在包含最低函数值的超矩形的归一化对角线的一半小于 len_tol 时终止优化。必须在 0 和 1 之间。默认值为 1e-6。

回调可调用,可选

一个回调函数,其签名是 callback(xk),其中 xk 表示到目前为止找到的最佳函数值。

返回:
res优化结果

优化结果表示为一个 OptimizeResult 对象。重要属性包括:x 解数组,success 一个布尔标志,指示优化器是否成功退出,以及 message 描述终止原因。有关其他属性的描述,请参见 OptimizeResult

注释

DIviding RECTangles (DIRECT) 是一种确定性的全局优化算法,能够通过在搜索空间中采样潜在解决方案来最小化受上下界约束的黑箱函数 [1]。该算法首先将搜索空间归一化为一个 n 维单位超立方体。它在超立方体的中心和 2n 个(n 是变量数量)更多点处采样函数,每个坐标方向采样 2 个点。利用这些函数值,DIRECT 然后将域划分为超矩形,每个超矩形以其采样点之一为中心。在每次迭代中,DIRECT 使用默认值为 1e-4 的 eps 参数选择一些现有的超矩形进行进一步划分。此划分过程继续进行,直到超过允许的最大迭代次数或最大函数评估次数,或者包含迄今为止找到的最小值的超矩形变得足够小。如果指定了 f_min,优化将在达到此函数值且在相对容差范围内时停止。DIRECT 的局部偏向变体(最初称为 DIRECT_L)[R02b79bde38b4-2]_ 默认使用。它使搜索更具局部偏向性,对于只有少数局部最小值的情况更为高效。

关于终止标准的说明:vol_tol 指的是包含迄今为止找到的最低函数值的超矩形的体积。随着问题维度的增加,该体积呈指数级减少。因此,对于更高维度的问题,应减少 vol_tol 以避免算法过早终止。对于 len_tol 则不适用:它指的是最大边长的一半(对于 locally_biased=True)或超矩形对角线的一半(对于 locally_biased=False)。

此代码基于 Gablonsky 等人在 https://ctk.math.ncsu.edu/SOFTWARE/DIRECTv204.tar.gz 提供的 DIRECT 2.0.4 Fortran 代码。原始版本最初通过 f2c 转换,然后由 Steven G. Johnson 于 2007 年 8 月为 NLopt 项目进行了清理和重新组织。direct 函数包装了 C 实现。

Added in version 1.9.0.

参考文献

[1]

Jones, D.R., Perttunen, C.D. & Stuckman, B.E. 不使用Lipschitz常数的Lipschitz优化。J Optim Theory Appl 79, 157-181 (1993).

[2]

Gablonsky, J., Kelley, C. 一种局部偏好的DIRECT算法形式。《全局优化杂志》21, 27-37 (2001)。

示例

以下示例是一个具有四个局部最小值的二维问题:最小化 Styblinski-Tang 函数(https://en.wikipedia.org/wiki/Test_functions_for_optimization)。

>>> from scipy.optimize import direct, Bounds
>>> def styblinski_tang(pos):
...     x, y = pos
...     return 0.5 * (x**4 - 16*x**2 + 5*x + y**4 - 16*y**2 + 5*y)
>>> bounds = Bounds([-4., -4.], [4., 4.])
>>> result = direct(styblinski_tang, bounds)
>>> result.x, result.fun, result.nfev
array([-2.90321597, -2.90321597]), -78.3323279095383, 2011

找到了正确的全局最小值,但函数评估次数非常多(2011次)。放宽终止容差 vol_tollen_tol 可以用于提前停止DIRECT。

>>> result = direct(styblinski_tang, bounds, len_tol=1e-3)
>>> result.x, result.fun, result.nfev
array([-2.9044353, -2.9044353]), -78.33230330754142, 207