scipy.optimize.

direct#

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可调用对象

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

bounds序列或 Bounds

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

  1. Bounds 类的实例。

  2. x 中每个元素的 (min, max) 对。

argstuple,可选

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

epsfloat,可选

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

maxfunint 或 None,可选

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

maxiterint,可选

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

locally_biasedbool,可选

如果为 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可调用对象,可选

具有签名 callback(xk) 的回调函数,其中 xk 表示目前找到的最佳函数值。

返回:
resOptimizeResult

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

备注

DIviding RECTangles (DIRECT) 是一种确定性的全局优化算法,能够通过在搜索空间中采样潜在的解来最小化黑盒函数,其变量受上下限约束 [1]。该算法首先将搜索空间归一化为 n 维单位超立方体。它在此超立方体的中心和另外 2n 个点(n 是变量的数量,每个坐标方向有 2 个)处对函数进行采样。使用这些函数值,DIRECT 然后将域划分为超矩形,每个超矩形恰好以一个采样点作为其中心。在每次迭代中,DIRECT 使用默认为 1e-4 的 eps 参数来选择一些现有的超矩形以进一步划分。此划分过程将继续进行,直到超过允许的最大迭代次数或最大函数评估次数,或者包含目前找到的最小值的超矩形变得足够小。如果指定了 f_min,则一旦在此函数值达到相对容差范围内,优化将停止。默认情况下使用 DIRECT 的局部偏置变体(最初称为 DIRECT_L) [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 实现。

在 1.9.0 版本中添加。

参考文献

[1]

Jones, D.R., Perttunen, C.D. & Stuckman, B.E. Lipschitzian optimization without the Lipschitz constant. J Optim Theory Appl 79, 157-181 (1993).

[2]

Gablonsky, J., Kelley, C. A Locally-Biased form of the DIRECT Algorithm. Journal of Global Optimization 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