scipy.optimize.differential_evolution

scipy.optimize.differential_evolution(func, bounds, args=(), strategy='best1bin', maxiter=1000, popsize=15, tol=0.01, mutation=(0.5, 1), recombination=0.7, seed=None, callback=None, disp=False, polish=True, init='latinhypercube', atol=0, updating='immediate', workers=1, constraints=(), x0=None)[源代码]

查找多元函数的全局最小值。

差分进化本质上是随机的(不使用梯度方法)来寻找最小值,可以搜索大范围的候选空间,但与传统的基于梯度的技术相比,通常需要更多的函数计算。

该算法归因于Storn和Price [1].

参数
func可调用

要最小化的目标函数。必须在表格中 f(x, *args) ,在哪里 x 是一维数组形式的参数,并且 args 是完全指定函数所需的任何附加固定参数的元组。

边界 :序列或 Bounds序列或

变量的界限。有两种方式可以指定边界:1. Bounds 班级。2. (min, max) 中每个元素的对 x 的优化参数的有限上下界。 func 。它被要求有 len(bounds) == len(x)len(bounds) 用于确定 x

args元组,可选

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

strategy字符串,可选

要使用的差异进化策略。应为以下之一:

  • “Best 1bin”

  • “Best 1exp”

  • “rand1exp”

  • “RANDOBEST 1EXP”

  • ‘CURRENT TO BEST 1EXP’

  • “Best 2exp”

  • “rand2exp”

  • “RANDOBEST 1BIN”

  • ‘当前到最佳1bin’

  • “Best 2bin”

  • “随机2bin”

  • “随机1bin”

默认值为‘Best 1bin’。

maxiter整型,可选

整个种群进化的最大世代数。函数求值的最大数量(无抛光)为: (maxiter + 1) * popsize * len(x)

popsize整型,可选

用于设置总人口规模的乘数。人口中有 popsize * len(x) 个人。如果通过 init 关键字。在使用时 init='sobol' 人口大小计算为2的下一个幂 popsize * len(x)

tol浮动,可选

收敛的相对容差,在以下情况下停止求解 np.std(pop) <= atol + tol * np.abs(np.mean(population_energies)) 、地点和地点 atoltol 分别是绝对公差和相对公差。

mutation浮点型或元组(浮点型,浮点型),可选

突变常数。在文献中,这也称为差异权重,用F表示。如果指定为浮点型,则应该在 [0, 2] 。如果指定为元组,则 (min, max) 使用抖动。抖动在逐代的基础上随机改变突变常数。该世代突变常数取自 U[min, max) 。抖动可以显著加快收敛速度。增加变异常数会增加搜索半径,但会减慢收敛速度。

recombination浮动,可选

复合常数应在范围内 [0, 1] 。在文献中,这也称为交叉概率,用CR表示。增加此值允许更多的突变体进入下一代,但会有种群稳定的风险。

seed :{无,整型, numpy.random.Generator{无,整型,

如果 seed 为无(或 np.random )、 numpy.random.RandomState 使用的是Singleton。如果 seed 是一个整型、一个新的 RandomState 实例,其种子设定为 seed 。如果 seed 已经是一个 GeneratorRandomState 实例,则使用该实例。指定 seed 用于可重复最小化。

disp布尔值,可选

打印评估结果 func 在每一次迭代中。

回调 :可调用, callback(xk, convergence=val) ,可选可调用的,

跟踪最小化进程的函数。 xk 是的当前值 x0val 表示总体收敛的分数值。什么时候 val 大于1,则函数暂停。如果回调返回 True ,则停止最小化(仍执行任何抛光)。

polish布尔值,可选

如果为True(默认值),则 scipy.optimize.minimize 使用 L-BFGS-B 最后利用该方法对最优种群成员进行磨光,使极小化程度略有提高。如果正在研究约束问题,则 trust-constr 方法,而不是使用。

init字符串或类似数组,可选

指定执行哪种类型的填充初始化。应为以下之一:

  • “拉丁超立方体”

  • “Sobol”

  • “哈尔顿”

  • “随机”

  • 指定初始填充的数组。数组应具有形状 (M, len(x)) ,其中M是总体大小,len(X)是参数数量。 init 被剪裁到 bounds 在使用之前。

默认值为“latinHypercube”。拉丁超立方体采样尝试最大限度地覆盖可用参数空间。

“sobol”和“halton”是更好的选择,并且更能最大化参数空间。“sobol”将强制使用初始人口大小,该大小计算为2的下一个幂 popsize * len(x) 。‘halton’没有要求,但效率稍低。看见 scipy.stats.qmc 了解更多详细信息。

“随机”随机初始化总体-这有可能发生群集的缺点,防止了整个参数空间被覆盖。例如,可以使用数组来指定总体,以在已知存在解的位置创建一组紧密的初始猜测,从而减少收敛时间。

atol浮动,可选

收敛的绝对容差,在以下情况下停止求解 np.std(pop) <= atol + tol * np.abs(np.mean(population_energies)) 、地点和地点 atoltol 分别是绝对公差和相对公差。

updating{‘立即’,‘延期’},可选

如果 'immediate' ,最优解向量在单代内不断更新 [4]. 这可以导致更快的收敛,因为试验向量可以利用在最佳解决方案中不断改进的优势。使用 'deferred' ,则每代更新一次最佳解向量。仅限 'deferred' 与并行化兼容,并且 workers 关键字可以覆盖此选项。

1.2.0 新版功能.

workers整型或映射型可调用,可选

如果 workers 是一个整数,人口细分为 workers 部分并并行计算(使用 multiprocessing.Pool )。提供-1以使用所有可用的CPU核心。或者,也可以提供类似于映射的可调用对象,例如 multiprocessing.Pool.map 用于并行评估人口。此评估按如下方式进行 workers(func, iterable) 。此选项将覆盖 updating 关键字至 updating='deferred' 如果 workers != 1 。要求 func 是可以腌制的。

1.2.0 新版功能.

constraints{NonLinearConstraint,LinearConstraint,Bound}

对求解器应用的约束,以及 bounds KWD。使用Lampinen的方法 [5].

1.4.0 新版功能.

x0无或类似数组,可选

提供最小化的初始猜测。一旦种群初始化,此向量将替换第一个(最佳)成员。即使在以下情况下也会进行此替换 init 给出了一个初始人口。

1.7.0 新版功能.

退货
resOptimizeResult

优化结果表示为 OptimizeResult 对象。重要属性包括: x 解决方案阵列, success 指示优化器是否成功退出的布尔标志 message 它描述了终止的原因。看见 OptimizeResult 有关其他属性的说明,请参见。如果 polish ,并通过抛光获得较低的最小值,则OptimizeResult还包含 jac 属性。如果最终解决方案不满足所应用的约束 success 将会是 False

注意事项

差分进化是一种基于随机种群的求解全局优化问题的方法。在每次通过群体时,该算法通过与其他候选解决方案混合来改变每个候选解决方案,以创建试探性候选解决方案。有几种策略 [2] 用于创建审判候选人,这比其他问题更适合一些问题。对于许多系统来说,“Best 1bin”策略是一个很好的起点。在这个策略中,随机选择两个群体成员。它们的差异被用来变异最好的成员(“Best 1bin”中的“Best”), \(b_0\) ,到目前为止:

\[b‘=b_0+突变*(种群 [随机0] -人口 [随机1] )\]

然后构造一个试验向量。从随机选择的第i个参数开始,用下式中的参数顺序填充(以模数表示)试验 b' 或者是最初的候选人。选择是否使用 b' 或者原始候选者的分布为二项分布(‘Best 1bin’中的‘bin’)-- [0, 1) is generated. If this number is less than the recombination constant then the parameter is loaded from b', otherwise it is loaded from the original candidate. The final parameter is always loaded from b'. Once the trial candidate is built its fitness is assessed. If the trial is better than the original candidate then it takes its place. If it is also better than the best overall candidate it also replaces that. To improve your chances of finding a global minimum use higher popsize values, with higher mutation and (dithering), but lower recombination values. This has the effect of widening the search radius, but slowing convergence. By default the best solution vector is updated continuously within a single iteration (updating='immediate'). This is a modification [4] 原来的差分进化算法可以更快地收敛,因为试向量可以立即受益于改进的解。要使用原始Storn and Price行为,每次迭代更新一次最佳解决方案,请设置 updating='deferred'

0.15.0 新版功能.

参考文献

1

斯托恩,R和普莱斯,K,微分进化-连续空间上全局优化的一个简单而有效的启发式方法,全球优化杂志,1997,11,341-359。

2

http://www1.icsi.berkeley.edu/~storn/code.html

3

http://en.wikipedia.org/wiki/Differential_evolution

4(1,2)

沃明顿,M.,Panaccione,C.,Matney,K.M.,Bowen,D.K.,使用遗传算法从X射线散射数据中表征结构,菲尔。翻译过来的。[中英文摘要]R.Soc.朗德。A,1999,357,2827-2848

5

差分进化算法的一种约束处理方法。2002年进化计算大会论文集。CEC‘02(分类表格02TH8600)。第二卷,IEEE,2002。

示例

让我们考虑最小化Rosenbrock函数的问题。此函数在以下位置实现 rosen 在……里面 scipy.optimize

>>> from scipy.optimize import rosen, differential_evolution
>>> bounds = [(0,2), (0, 2), (0, 2), (0, 2), (0, 2)]
>>> result = differential_evolution(rosen, bounds)
>>> result.x, result.fun
(array([1., 1., 1., 1., 1.]), 1.9216496320061384e-19)

现在重复,但要并行化。

>>> bounds = [(0,2), (0, 2), (0, 2), (0, 2), (0, 2)]
>>> result = differential_evolution(rosen, bounds, updating='deferred',
...                                 workers=2)
>>> result.x, result.fun
(array([1., 1., 1., 1., 1.]), 1.9216496320061384e-19)

让我们试着做一个有约束的最小化

>>> from scipy.optimize import NonlinearConstraint, Bounds
>>> def constr_f(x):
...     return np.array(x[0] + x[1])
>>>
>>> # the sum of x[0] and x[1] must be less than 1.9
>>> nlc = NonlinearConstraint(constr_f, -np.inf, 1.9)
>>> # specify limits using a `Bounds` object.
>>> bounds = Bounds([0., 0.], [2., 2.])
>>> result = differential_evolution(rosen, bounds, constraints=(nlc),
...                                 seed=1)
>>> result.x, result.fun
(array([0.96633867, 0.93363577]), 0.0011361355854792312)

接下来,找出Ackley函数(https://en.wikipedia.org/wiki/Test_functions_for_optimization).的最小值

>>> from scipy.optimize import differential_evolution
>>> import numpy as np
>>> def ackley(x):
...     arg1 = -0.2 * np.sqrt(0.5 * (x[0] ** 2 + x[1] ** 2))
...     arg2 = 0.5 * (np.cos(2. * np.pi * x[0]) + np.cos(2. * np.pi * x[1]))
...     return -20. * np.exp(arg1) - np.exp(arg2) + 20. + np.e
>>> bounds = [(-5, 5), (-5, 5)]
>>> result = differential_evolution(ackley, bounds)
>>> result.x, result.fun
(array([ 0.,  0.]), 4.4408920985006262e-16)