brute#
- scipy.optimize.brute(func, ranges, args=(), Ns=20, full_output=0, finish=<function fmin>, disp=False, workers=1)[源代码]#
通过蛮力法在给定范围内最小化函数。
使用“蛮力法”,即在多维网格的每个点计算函数的值,寻找函数的全局最小值。
函数在范围内的任何地方都将使用函数的第一次调用的数据类型进行计算,如
vectorize
NumPy 函数所强制执行的。当full_output=True
时返回的函数计算的值和类型还受finish
参数的影响(参见注释)。蛮力法效率低下,因为网格点的数量呈指数增长——要评估的网格点数为
Ns ** len(x)
。结果,即使是粗略的网格间隔,中等规模的问题也可能需要很长时间才能运行,和/或遇到内存限制。- 参数:
- func可调用的
要最小化的目标函数。必须采用
f(x, *args)
的形式,其中x
是以 1-D 数组形式提供自变量,而args
是需要用来完全指定函数的任何其他固定参数元组。- ranges元组
ranges 元组的每个分量都必须是“切片对象”,或者采用
(low, high)
形式的 range 元组。程序使用它们来创建将计算目标函数的点的网格。有关更多详细信息,请参阅注释 2。- args元组,可选
需要用来完全指定函数的任何其他固定参数。
- Nsint,可选
如果没有另行指定,则沿轴的网格点数量。请参阅注释 2。
- full_outputbool,可选
如果为 True,则返回评估网格和它上面的目标函数值。
- finish可调用对象,可选
用作蛮力最小化结果的初始猜测调用的优化函数。finish 应接受 func 和初始猜测作为位置参数,并接受 args 作为关键字参数。它还可以接受 full_output 和/或 disp 作为关键字参数。如果要使用“改进型”函数,则使用 None。有关更多详细信息,请参阅注释。
- dispbool,可选
设置为 True 以从 finish 可调用对象打印收敛消息。
- workersint 或类似映射的可调用对象,可选
如果 workers 是一个整数,网格将被细分为 workers 个部分,并行进行评估(使用
multiprocessing.Pool
)。提供 -1 以为进程使用所有可用内核。另外提供类似映射的可调用对象,例如 multiprocessing.Pool.map,以并行评估网格。此评估作为workers(func, iterable)
进行。要求 func 是可 pickle 的。在 1.3.0 版本中添加。
- 返回:
- x0ndarray
一个 1-D 数组,其中包含目标函数在最小值处点的坐标。(有关返回哪个点,请参见注释 1。)
- fvalfloat
点x0 处函数值。(当full_output 为真时返回。)
- gridtuple
评估网格的表示。其长度与x0 相同。(当full_output 为真时返回。)
- Joutndarray
评估网格各点的函数值,即
Jout = func(*grid)
。(当full_output 为真时返回。)
注释
注释 1:该程序找到目标函数发生最小值的网格点。如果finish 为无,则该点是返回点。当全局最小值发生在网格边界内(或不远在其外部),且网格足够精细时,该点将处于全局最小值附近。
但是,用户通常使用其他优化程序来“修正”网格点值,即在brute 的最佳网格点附近寻找更精密的(局部)最小值。
brute
函数的finish 选项提供了一种执行此操作的便捷方法。所使用的任何修正程序都必须以brute 的输出作为其初始猜测值,将brute 的输入值作为关键字参数,否则会引发错误。它还可以full_output 和/或disp 作为关键字参数。brute
假设 finish 函数返回一个OptimizeResult
对象或一个形式如(xmin, Jmin, ... , statuscode)
的元组,其中xmin
为参数的极小值,Jmin
为目标函数的极小值,“...” 可以是其他一些返回的值(未使用brute
),statuscode
为 finish 程序的状态代码。请注意,当 finish 不为 None 时,返回的值是 finish 程序的值,不是 网格点的值。因此,尽管
brute
将其搜索限制在输入网格点上,finish 程序的结果通常不会与任何网格点一致,并且可能会超出网格的边界。因此,如果仅需要在提供的网格点上找到最小值,请务必传入 finish=None。注意 2:点网格是一个
numpy.mgrid
对象。对于brute
,ranges 和 Ns 输入的影响如下。ranges 元组的每个组成部分都可以是一个切片对象或一个二元组,给出值范围,例如 (0, 5)。如果组成部分是一个切片对象,brute
直接使用它。如果该组成部分是一个二元组范围,brute
在内部将其转换为一个插值范围,通过 Ns 个点由其低值到高值(包括低值和高值)。示例
我们说明了使用
brute
寻求作为正定二次和两个深“高斯形”凹坑的和来给出的两个变量函数的全局最小值。具体而言,将目标函数 f 定义为其他三个函数的和,f = f1 + f2 + f3
。我们认为这些函数分别具有签名(z, *params)
,其中z = (x, y)
且params
及函数定义如下。>>> import numpy as np >>> params = (2, 3, 7, 8, 9, 10, 44, -1, 2, 26, 1, -2, 0.5) >>> def f1(z, *params): ... x, y = z ... a, b, c, d, e, f, g, h, i, j, k, l, scale = params ... return (a * x**2 + b * x * y + c * y**2 + d*x + e*y + f)
>>> def f2(z, *params): ... x, y = z ... a, b, c, d, e, f, g, h, i, j, k, l, scale = params ... return (-g*np.exp(-((x-h)**2 + (y-i)**2) / scale))
>>> def f3(z, *params): ... x, y = z ... a, b, c, d, e, f, g, h, i, j, k, l, scale = params ... return (-j*np.exp(-((x-k)**2 + (y-l)**2) / scale))
>>> def f(z, *params): ... return f1(z, *params) + f2(z, *params) + f3(z, *params)
因此,目标函数可能在此函数所组成的三个函数各自的最小值附近具有局部最小值。要使用
fmin
优化其网格点结果,我们可以继续如下>>> rranges = (slice(-4, 4, 0.25), slice(-4, 4, 0.25)) >>> from scipy import optimize >>> resbrute = optimize.brute(f, rranges, args=params, full_output=True, ... finish=optimize.fmin) >>> resbrute[0] # global minimum array([-1.05665192, 1.80834843]) >>> resbrute[1] # function value at global minimum -3.4085818767
请注意,如果已将 finish 设置为 None,则我们会得到网格点 [-1.0 1.75],其中舍入函数值为 -2.892。