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,) 的一维数组,args 是完全指定函数所需的固定参数元组。

bounds序列 或 Bounds

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

  1. Bounds 类的实例。

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

args元组, 可选

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

eps浮点数, 可选

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

maxfun整数 或 无, 可选

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

maxiter整数, 可选

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

locally_biased布尔值, 可选

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

f_min浮点数, 可选

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

f_min_rtol浮点数, 可选

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

vol_tol浮点数, 可选

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

len_tol浮点数, 可选

如果 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