SciPy-1-12-中文文档-二十五-

48 阅读39分钟

SciPy 1.12 中文文档(二十五)

原文:docs.scipy.org/doc/scipy-1.12.0/index.html

scipy.optimize.linprog

原文:docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.optimize.linprog.html#scipy.optimize.linprog

scipy.optimize.linprog(c, A_ub=None, b_ub=None, A_eq=None, b_eq=None, bounds=None, method='highs', callback=None, options=None, x0=None, integrality=None)

线性规划:最小化线性目标函数,受线性等式和不等式约束限制。

线性规划解决如下形式的问题:

[\begin{split}\min_x \ & c^T x \ \mbox{使得} \ & A_{ub} x \leq b_{ub},\ & A_{eq} x = b_{eq},\ & l \leq x \leq u ,\end{split}]

其中 (x) 是决策变量向量;(c), (b_{ub}), (b_{eq}), (l), 和 (u) 是向量;(A_{ub}) 和 (A_{eq}) 是矩阵。

或者说:

  • 最小化

  • c @ x 
    
  • 使得

  • A_ub @ x <= b_ub
    A_eq @ x == b_eq
    lb <= x <= ub 
    

注意,默认情况下 lb = 0ub = None。可以使用 bounds 指定其他边界。

参数:

c 1-D 数组

要最小化的线性目标函数的系数。

A_ub 2-D 数组,可选

不等约束矩阵。A_ub 的每一行指定 x 的线性不等式约束的系数。

b_ub 1-D 数组,可选

不等约束向量。每个元素表示对应的A_ub @ x的上限。

A_eq 2-D 数组,可选

等式约束矩阵。A_eq 的每一行指定 x 的线性等式约束的系数。

b_eq 1-D 数组,可选

等式约束向量。A_eq @ x 的每个元素必须等于 b_eq 的对应元素。

bounds 序列,可选

对于 x 中每个元素的 (min, max) 对序列,定义决策变量的最小和最大值。如果提供单个元组 (min, max),则 minmax 将作为所有决策变量的边界。使用 None 表示无边界。例如,默认边界 (0, None) 表示所有决策变量非负,而对 (None, None) 表示无任何边界,即所有变量可以是任意实数。

method 字符串,可选

用于解决标准形式问题的算法。支持 ‘highs’(默认),‘highs-ds’,‘highs-ipm’,‘interior-point’(遗留),‘revised simplex’(遗留)和 ‘simplex’(遗留)。遗留方法已弃用,将在 SciPy 1.11.0 中移除。

callback 可调用对象,可选

如果提供了回调函数,则算法的每次迭代至少调用一次。回调函数必须接受单一的scipy.optimize.OptimizeResult,包含以下字段:

x1-D 数组

当前解向量。

funfloat

目标函数 c @ x 的当前值。

successbool

True when the algorithm has completed successfully.

slack1-D 数组

松弛变量的(名义上的正)值,b_ub - A_ub @ x

con1-D 数组

等式约束的(名义上的零)残差,b_eq - A_eq @ x

phaseint

正在执行的算法阶段。

statusint

表示算法状态的整数。

0 : 优化正常进行。

1 : 达到迭代限制。

2 : Problem appears to be infeasible.

3 : 问题似乎无界。

4 : 遇到数值困难。

nitint

当前迭代次数。

messagestr

描述算法状态的字符串。

目前 HiGHS 方法不支持回调函数。

optionsdict, optional

求解器选项的字典。所有方法都接受以下选项:

maxiterint

执行的最大迭代次数。默认值:请参阅特定方法的文档。

dispbool

设置为 True 打印收敛消息。默认值:False

presolvebool

设置为 False 禁用自动预处理。默认值:True

除 HiGHS 求解器外,所有方法都接受:

tolfloat

决定残差何时“足够接近”零以被视为精确零的公差。

autoscalebool

设置为 True 自动执行均衡化。如果约束中的数值在数量级上相隔甚远,则考虑使用此选项。默认值:False

rrbool

设置为 False 禁用自动冗余移除。默认值:True

rr_methodstring

在预处理后从等式约束矩阵中识别和删除多余行的方法。对于输入稠密的问题,可用的冗余移除方法有:

“SVD”:

反复对矩阵执行奇异值分解,基于左奇异向量中的非零元素检测冗余行,对于接近完全秩的矩阵可能很快。

“pivot”:

使用[5]中介绍的算法来识别多余的行。

“ID”:

使用随机插值分解。识别矩阵转置的未在完全秩插值分解中使用的列。

None:

如果矩阵接近满秩,即矩阵秩与行数之差小于五,则使用“svd”。否则使用“pivot”。此默认行为可能会在未经通知的情况下更改。

默认值:无。对于输入稀疏的问题,此选项将被忽略,并使用基于“pivot”的算法,该算法见[5]

对于特定方法的选项,请参见show_options('linprog')

x01-D 数组,可选

决策变量的猜测值,将由优化算法细化。当前仅由‘revised simplex’方法使用,并且仅当x0表示基本可行解时才能使用。

integrality1-D 数组或整数,可选

指示每个决策变量整数约束类型。

0:连续变量;没有整数约束。

1:整数变量;决策变量必须在bounds内为整数。

2:半连续变量;决策变量必须在bounds内或取值0

3:半整数变量;决策变量必须在bounds内为整数或取值0

默认情况下,所有变量均为连续的。

对于混合整数约束,请提供一个形状为c.shape的数组。为了从较短的输入推断出每个决策变量的约束条件,参数将使用np.broadcast_to广播到c.shape

当前仅由'highs'方法使用,否则忽略。

返回:

resOptimizeResult

一个scipy.optimize.OptimizeResult,包含以下字段。请注意,字段的返回类型可能取决于优化是否成功,因此建议在依赖其他字段之前检查OptimizeResult.status

x1-D 数组

使目标函数最小化同时满足约束条件的决策变量值。

funfloat

目标函数的最优值c @ x

slack1-D 数组

松弛变量(通常为正值),b_ub - A_ub @ x

con1-D 数组

等式约束的(通常为零的)残差,b_eq - A_eq @ x

successbool

找到最优解时为True

状态整数

表示算法退出状态的整数。

0:优化成功终止。

1:达到迭代限制。

2:问题似乎无解。

3:问题似乎无界。

4:遇到数值困难。

nitint

所有阶段中执行的总迭代次数。

messagestr

表示算法退出状态的字符串描述。

另请参阅

show_options

求解器接受的附加选项。

注意

本节描述可以通过‘method’参数选择的可用求解器。

‘highs-ds’‘highs-ipm’ 是 HiGHS 单纯形和内点法求解器的接口[13]‘highs’(默认)会自动选择两者之一。这些是 SciPy 中最快的线性规划求解器,特别适用于大型稀疏问题;哪个更快取决于问题本身。其他求解器(‘interior-point’‘revised simplex’‘simplex’)是遗留方法,将在 SciPy 1.11.0 中移除。

highs-ds 方法是 C++ 高性能双修订单纯形实现(HSOL)的包装器[13][14]highs-ipm 方法是 C++ 内点法实现的包装器[13],它具有交叉路由,因此与单纯形求解器一样精确。highs 方法会自动选择两者中的一种。对于涉及 linprog 的新代码,建议明确选择这三种方法值之一。

自版本 1.6.0 新增。

interior-point 方法使用在[4]中概述的原始-对偶路径跟踪算法。此算法支持稀疏约束矩阵,对于大型稀疏问题特别快速。然而,返回的解可能比单纯形方法稍微不准确,并且通常不与约束定义的多面体顶点对应。

自版本 1.0.0 新增。

修订单纯形法 方法使用修订的单纯形法,如[9]中所述,但在算法的每次迭代中,使用基础矩阵的因子分解[11]来有效地维护和解决线性系统。

自版本 1.3.0 新增。

simplex 方法使用 Dantzig 单纯形算法的传统全表实现[1][2]是 Nelder-Mead 单纯形)。此算法包含以保持向后兼容性和教育目的。

自版本 0.15.0 新增。

在应用 interior-pointrevised simplexsimplex 之前,基于[8]的预处理过程尝试识别平凡的不可行性、平凡的无界性和潜在的问题简化。具体来说,它检查以下情况:

  • A_eqA_ub 中的零行,表示平凡约束;

  • A_eqA_ub 中的零列,表示无约束变量;

  • 列单体在 A_eq 中,表示固定变量;

  • 列单体在 A_ub 中,表示简单边界。

如果预处理显示问题无界(例如,一个无约束和无界变量具有负成本)或不可行(例如,A_eq中的零行与b_eq中的非零对应),求解器将以适当的状态代码终止。请注意,预处理一旦检测到任何无界性的迹象就会终止;因此,当实际上问题是不可行时(但尚未检测到不可行性),可能会报告问题是无界的。因此,如果重要的是知道问题实际上是否不可行,请使用选项presolve=False重新解决问题。

如果在预处理的单次通行中既未检测到不可行性也未检测到无界性,则在可能的情况下收紧界限并从问题中删除固定变量。然后,删除A_eq矩阵的线性相关行(除非它们代表不可行性),以避免主要求解例程中的数值困难。请注意,几乎线性相关的行(在规定的容差内)也可以被删除,这在极少数情况下可能会改变最优解。如果这是一个问题,请从您的问题表达中消除冗余并使用选项rr=Falsepresolve=False运行。

这里可以进行几个潜在的改进:应该实现在[8]中概述的额外预处理检查,应该多次运行预处理例程(直到无法进一步简化为止),并且应该在冗余删除程序中实现[5]的更多效率改进。

经过预处理后,通过将(加紧的)简单界限转换为上界约束,为不等式约束引入非负松弛变量,并将无界变量表示为两个非负变量的差异,问题转换为标准形式。可选地,问题通过均衡转换自动进行缩放[12]。所选算法解决标准形式问题,并通过后处理程序将结果转换为原问题的解决方案。

参考文献

[1]

Dantzig, George B., 线性规划及其扩展。兰德公司研究学习普林斯顿大学出版社,普林斯顿,新泽西州,1963 年。

[2]

Hillier, S.H. 和 Lieberman, G.J. (1995), “数学规划导论”, 麦格劳-希尔, 第四章。

[3]

Bland, Robert G. 简单法的新有限枢轴规则。运筹学数学(2),1977 年:103-107 页。

[4]

Andersen, Erling D. 和 Knud D. Andersen. “MOSEK 内点优化器用于线性规划:同质算法的实现”。高性能优化。斯普林格美国出版,2000 年。197-232 页。

[5] (1,2,3)

Andersen, Erling D. “在大规模线性规划中找到所有线性相关的行。” 优化方法和软件 6.3(1995):219-227 页。

[6]

弗洛伊德,罗伯特·M。“基于牛顿方法的线性规划原始-对偶内点方法。”未发表的课程笔记,2004 年 3 月。可在 2017 年 2 月 25 日访问 ocw.mit.edu/courses/sloan-school-of-management/15-084j-nonlinear-programming-spring-2004/lecture-notes/lec14_int_pt_mthd.pdf

[7]

福勒,罗伯特。“通过内点方法解线性规划问题。”未发表的课程笔记,2005 年 8 月 26 日。可在 2017 年 2 月 25 日访问 www.4er.org/CourseNotes/Book%20B/B-III.pdf

[8] (1,2)

安德森,埃尔林·D.,和克努德·D. 安德森。“线性规划中的预处理。”数学规划 71.2 (1995): 221-245。

[9]

贝茨马斯,迪米特里斯,和 J. Tsitsiklis。“线性规划导论。”Athena Scientific 1 (1997): 997。

[10]

安德森,埃尔林·D.,等人。大规模线性规划内点方法的实现。HEC/日内瓦大学,1996 年。

[11]

巴特尔斯,理查德·H。“单纯形方法的稳定化。”Journal in Numerische Mathematik 16.5 (1971): 414-434。

[12]

汤姆林,J. A.。“关于缩放线性规划问题。”数学规划研究 4 (1975): 146-166。

[13] (1,2,3)

黄甫,秦,加拉博娃,伊娃,费尔德迈尔,马克,和霍尔,J. A. J.。“HiGHS - 用于线性优化的高性能软件。”highs.dev/

[14]

黄甫,秦,和霍尔,J. A. J.。“对偶修订单纯形方法的并行化。”数学规划计算,10 (1),119-142,2018 年。DOI: 10.1007/s12532-017-0130-5

示例

考虑以下问题:

[\begin{split}\min_{x_0, x_1} \ -x_0 + 4x_1 & \ \mbox{这样的} \ -3x_0 + x_1 & \leq 6,\ -x_0 - 2x_1 & \geq -4,\ x_1 & \geq -3.\end{split}]

问题的表述形式不符合linprog接受的格式。通过将“大于”不等式约束转换为“小于”不等式约束,同时将两边乘以(-1)的方法可以轻松解决这个问题。还需注意,最后一个约束实际上是简单的界限条件(-3 \leq x_1 \leq \infty)。最后,由于(x_0)没有边界,我们必须明确指定边界(-\infty \leq x_0 \leq \infty),因为默认情况下变量是非负的。将系数收集到数组和元组中后,该问题的输入为:

>>> from scipy.optimize import linprog
>>> c = [-1, 4]
>>> A = [[-3, 1], [1, 2]]
>>> b = [6, 4]
>>> x0_bounds = (None, None)
>>> x1_bounds = (-3, None)
>>> res = linprog(c, A_ub=A, b_ub=b, bounds=[x0_bounds, x1_bounds])
>>> res.fun
-22.0
>>> res.x
array([10., -3.])
>>> res.message
'Optimization terminated successfully. (HiGHS Status 7: Optimal)' 

边际(也称为对偶值 / 影子价格 / 拉格朗日乘子)和剩余量(余量)也是可用的。

>>> res.ineqlin
 residual: [ 3.900e+01  0.000e+00]
 marginals: [-0.000e+00 -1.000e+00] 

例如,因为与第二个不等式约束相关联的边际为 -1,我们预期如果我们在第二个不等式约束的右侧添加一个小量eps,目标函数的最优值将减少eps

>>> eps = 0.05
>>> b[1] += eps
>>> linprog(c, A_ub=A, b_ub=b, bounds=[x0_bounds, x1_bounds]).fun
-22.05 

Also, because the residual on the first inequality constraint is 39, we can decrease the right hand side of the first constraint by 39 without affecting the optimal solution.

>>> b = [6, 4]  # reset to original values
>>> b[0] -= 39
>>> linprog(c, A_ub=A, b_ub=b, bounds=[x0_bounds, x1_bounds]).fun
-22.0 

scipy.optimize.linprog_verbose_callback

原文:docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.optimize.linprog_verbose_callback.html#scipy.optimize.linprog_verbose_callback

scipy.optimize.linprog_verbose_callback(res)

A sample callback function demonstrating the linprog callback interface. This callback produces detailed output to sys.stdout before each iteration and after the final iteration of the simplex algorithm.

参数:

res一个包含以下字段的scipy.optimize.OptimizeResult

x1-D array

优化线性规划问题的独立变量向量。

funfloat

目标函数的值。

successbool

如果算法成功找到最优解,则为 True。

slack1-D array

松弛变量的值。每个松弛变量对应一个不等式约束。如果松弛为零,则相应约束活跃。

con1-D array

等式约束的残差(通常为零),即 b - A_eq @ x

phaseint

正在执行的优化阶段。在第 1 阶段,寻找基本可行解,并且 T 有一行额外表示备用目标函数。

statusint

优化的退出状态的整数表示:

0 : Optimization terminated successfully
1 : Iteration limit reached
2 : Problem appears to be infeasible
3 : Problem appears to be unbounded
4 : Serious numerical difficulties encountered 

nitint

执行的迭代次数。

messagestr

优化退出状态的字符串描述。

scipy.optimize.linear_sum_assignment

原文:docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.optimize.linear_sum_assignment.html#scipy.optimize.linear_sum_assignment

scipy.optimize.linear_sum_assignment()

解决线性和分配问题。

参数:

cost_matrix数组

二分图的成本矩阵。

maximize布尔值(默认为 False)

计算最大权重匹配是否为真。

返回:

row_ind, col_ind数组

一个包含行索引和相应列索引的数组,给出最优分配。可以计算分配的成本为cost_matrix[row_ind, col_ind].sum()。行索引将被排序;在方形成本矩阵的情况下,它们将等于numpy.arange(cost_matrix.shape[0])

另见

scipy.sparse.csgraph.min_weight_full_bipartite_matching

用于稀疏输入

注意

线性和分配问题[1]也称为双分图中的最小权重匹配。问题实例由矩阵 C 描述,其中每个 C[i,j]是第一部分集合的顶点 i(一个“工作者”)和第二部分集合的顶点 j(一个“工作”)匹配的成本。目标是找到最小成本的工作者与工作的完全分配。

形式上,设 X 是一个布尔矩阵,其中(X[i,j] = 1)当且仅当第 i 行分配给第 j 列。然后,最优分配的成本为

[\min \sum_i \sum_j C_{i,j} X_{i,j}]

在矩阵 X 是方形的情况下,每行被分配给恰好一个列,每列被分配给恰好一个行。

此函数还可以解决经典分配问题的一般化,其中成本矩阵是矩形的。如果它的行数多于列数,则不需要将每行都分配给列,反之亦然。

此实现是一个修改的 Jonker-Volgenant 算法,没有初始化,描述在参考文献中。[2]

0.17.0 版中的新功能。

参考

[1]

en.wikipedia.org/wiki/Assignment_problem

[2]

DF Crouse. On implementing 2D rectangular assignment algorithms. IEEE Transactions on Aerospace and Electronic Systems, 52(4):1679-1696, August 2016, DOI:10.1109/TAES.2016.140952

示例

>>> import numpy as np
>>> cost = np.array([[4, 1, 3], [2, 0, 5], [3, 2, 2]])
>>> from scipy.optimize import linear_sum_assignment
>>> row_ind, col_ind = linear_sum_assignment(cost)
>>> col_ind
array([1, 0, 2])
>>> cost[row_ind, col_ind].sum()
5 

scipy.optimize.quadratic_assignment

原文链接:docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.optimize.quadratic_assignment.html#scipy.optimize.quadratic_assignment

scipy.optimize.quadratic_assignment(A, B, method='faq', options=None)

近似解决二次分配问题和图匹配问题。

二次分配解决以下形式的问题:

[\begin{split}\min_P & \ {\ \text{trace}(A^T P B P^T)}\ \mbox{s.t. } & {P \ \epsilon \ \mathcal{P}}\\end{split}]

其中(\mathcal{P})是所有排列矩阵的集合,(A)和(B)是方阵。

图匹配试图最大化相同的目标函数。此算法可以看作是找到两个图的节点对齐,使得诱导边不一致的数量最小,或者在加权图的情况下,边权重差的平方和最小。

注意,二次分配问题是 NP-难的。这里给出的结果是近似值,并不保证最优。

参数:

A2-D 数组,方阵

目标函数中的方阵(A)。

B2-D 数组,方阵

目标函数中的方阵(B)。

methodstr in {‘faq’, ‘2opt’}(默认:‘faq’)

解决问题的算法。‘faq’(默认)和‘2opt’可用。

optionsdict,可选

求解器选项的字典。所有求解器都支持以下内容:

maximizebool(默认:False)

如果为True,则最大化目标函数。

partial_match2-D 整数数组,可选(默认:None)

修复匹配的部分,也称为“种子”[2]

partial_match的每一行指定了匹配节点对:A 的节点partial_match[i, 0]B的节点partial_match[i, 1]匹配。数组的形状为(m, 2),其中m不大于节点数nn

rng{None, int, numpy.random.Generator,

numpy.random.RandomState,可选

如果seed为 None(或np.random),则使用numpy.random.RandomState单例。如果seed为整数,则使用一个带有seed种子的新RandomState实例。如果seed已经是GeneratorRandomState实例,则使用该实例。

有关特定方法的选项,请参阅show_options('quadratic_assignment')

返回:

resOptimizeResult

OptimizeResult 包含以下字段。

col_ind1-D 数组

对应于B节点的最佳排列的列索引。

funfloat

解决方案的目标值。

nitint

在优化过程中执行的迭代次数。

注释

默认方法‘faq’ 使用快速近似 QAP 算法 [1]; 它通常提供了速度和精度的最佳组合。方法‘2opt’ 可能计算成本高,但可能是一个有用的替代方案,或者用来优化另一种方法返回的解。

参考文献

[1]

J.T. Vogelstein, J.M. Conroy, V. Lyzinski, L.J. Podrazik, S.G. Kratzer, E.T. Harley, D.E. Fishkind, R.J. Vogelstein, 和 C.E. Priebe,“用于图匹配的快速近似二次规划”,PLOS one,vol. 10, no. 4, p. e0121002, 2015, DOI:10.1371/journal.pone.0121002

[2]

D. Fishkind, S. Adali, H. Patsolic, L. Meng, D. Singh, V. Lyzinski, C. Priebe,“种子图匹配”,Pattern Recognit. 87 (2019): 203-215, DOI:10.1016/j.patcog.2018.09.014

[3]

“2-opt”,维基百科。en.wikipedia.org/wiki/2-opt

示例

>>> import numpy as np
>>> from scipy.optimize import quadratic_assignment
>>> A = np.array([[0, 80, 150, 170], [80, 0, 130, 100],
...               [150, 130, 0, 120], [170, 100, 120, 0]])
>>> B = np.array([[0, 5, 2, 7], [0, 0, 3, 8],
...               [0, 0, 0, 3], [0, 0, 0, 0]])
>>> res = quadratic_assignment(A, B)
>>> print(res)
 fun: 3260
 col_ind: [0 3 2 1]
 nit: 9 

查看col_indfun 之间的关系,使用col_ind 形成找到的最佳排列矩阵,然后评估目标函数 (f(P) = trace(A^T P B P^T )).

>>> perm = res['col_ind']
>>> P = np.eye(len(A), dtype=int)[perm]
>>> fun = np.trace(A.T @ P @ B @ P.T)
>>> print(fun)
3260 

或者,为了避免显式构造排列矩阵,直接对距离矩阵的行和列进行排列。

>>> fun = np.trace(A.T @ B[perm][:, perm])
>>> print(fun)
3260 

尽管一般情况下不能保证,quadratic_assignment 恰好找到了全局最优解。

>>> from itertools import permutations
>>> perm_opt, fun_opt = None, np.inf
>>> for perm in permutations([0, 1, 2, 3]):
...     perm = np.array(perm)
...     fun = np.trace(A.T @ B[perm][:, perm])
...     if fun < fun_opt:
...         fun_opt, perm_opt = fun, perm
>>> print(np.array_equal(perm_opt, res['col_ind']))
True 

这是一个例子,其中默认方法‘faq’ 找不到全局最优解。

>>> A = np.array([[0, 5, 8, 6], [5, 0, 5, 1],
...               [8, 5, 0, 2], [6, 1, 2, 0]])
>>> B = np.array([[0, 1, 8, 4], [1, 0, 5, 2],
...               [8, 5, 0, 5], [4, 2, 5, 0]])
>>> res = quadratic_assignment(A, B)
>>> print(res)
 fun: 178
 col_ind: [1 0 3 2]
 nit: 13 

如果精度很重要,请考虑使用‘2opt’ 来优化解决方案。

>>> guess = np.array([np.arange(len(A)), res.col_ind]).T
>>> res = quadratic_assignment(A, B, method="2opt",
...                            options = {'partial_guess': guess})
>>> print(res)
 fun: 176
 col_ind: [1 2 3 0]
 nit: 17 

scipy.optimize.approx_fprime

原文:docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.optimize.approx_fprime.html#scipy.optimize.approx_fprime

scipy.optimize.approx_fprime(xk, f, epsilon=1.4901161193847656e-08, *args)

标量或向量值函数的有限差分近似的导数。

如果函数从(R^n)映射到(R^m),其导数形成一个称为雅可比矩阵的 m-by-n 矩阵,其中元素((i, j))是*f[i]*对xk[j]的偏导数。

参数:

xkarray_like

要确定f的梯度的坐标向量。

fcallable

要估计其导数的函数。具有签名f(xk, *args)的函数,其中xk是形状为 1-D 数组的参数,args是一个元组,包含完全指定函数所需的任何其他固定参数。传递给该函数的参数xk是形状为(n,)的 ndarray(即使 n=1 也不是标量)。它必须返回形状为(m,)的类似 1-D 数组或标量。

从版本 1.9.0 开始更改:f现在能够返回类似 1-D 数组的值,其中估计了((m, n))雅可比矩阵。

epsilon{float, array_like},可选

用于确定函数梯度的xk的增量。如果是标量,则对所有偏导数使用相同的有限差分增量。如果是数组,则应该包含xk的每个元素的一个值。默认为sqrt(np.finfo(float).eps),大约是 1.49e-08。

*argsargs,可选

传递给f的其他参数。

返回:

jacndarray

fxk的偏导数。

另请参见

check_grad

检查梯度函数相对于 approx_fprime 的正确性。

注意

函数梯度由前向有限差分公式确定:

 f(xk[i] + epsilon[i]) - f(xk[i])
f'[i] = ---------------------------------
                    epsilon[i] 

示例

>>> import numpy as np
>>> from scipy import optimize
>>> def func(x, c0, c1):
...     "Coordinate vector `x` should be an array of size two."
...     return c0 * x[0]**2 + c1*x[1]**2 
>>> x = np.ones(2)
>>> c0, c1 = (1, 200)
>>> eps = np.sqrt(np.finfo(float).eps)
>>> optimize.approx_fprime(x, func, [eps, np.sqrt(200) * eps], c0, c1)
array([   2\.        ,  400.00004198]) 

scipy.optimize.check_grad

原文:docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.optimize.check_grad.html#scipy.optimize.check_grad

scipy.optimize.check_grad(func, grad, x0, *args, epsilon=1.4901161193847656e-08, direction='all', seed=None)

通过将其与梯度的(前向)有限差逼近比较来检查梯度函数的正确性。

参数:

funccallable func(x0, *args)

要检查其导数的函数。

gradcallable grad(x0, *args)

func的雅可比矩阵。

x0ndarray

检查 grad 是否与使用 func 的前向差分逼近的梯度一致的点。

args*args, optional

传递给 funcgrad 的额外参数。

epsilonfloat, optional

用于有限差逼近的步长大小。默认为 sqrt(np.finfo(float).eps),约为 1.49e-08。

directionstr, optional

如果设为 'random',则使用沿随机向量的梯度来检查 grad 是否与使用 func 的前向差分逼近一致。默认情况下为 'all',此时考虑所有的单热方向向量以检查 grad。如果 func 是矢量值函数,则只能使用 'all'

seed{None, int, numpy.random.Generator, numpy.random.RandomState}, optional

如果 seed 为 None(或 np.random),则使用numpy.random.RandomState 单例。如果 seed 是整数,则使用新的 RandomState 实例,并以 seed 为种子。如果 seed 已经是 GeneratorRandomState 实例,则使用该实例。指定 seed 可以重现此函数的返回值。使用此种子生成的随机数影响计算梯度的随机向量。注意当 direction 参数设置为 ‘random’ 时才使用 seed

返回:

errfloat

两个向量之间差的平方和的平方根(即 2-范数),即 grad(x0, *args) 和在点 x0 使用 func 的有限差逼近 grad 的差异。

另请参见

approx_fprime

示例

>>> import numpy as np
>>> def func(x):
...     return x[0]**2 - 0.5 * x[1]**3
>>> def grad(x):
...     return [2 * x[0], -1.5 * x[1]**2]
>>> from scipy.optimize import check_grad
>>> check_grad(func, grad, [1.5, -1.5])
2.9802322387695312e-08  # may vary
>>> rng = np.random.default_rng()
>>> check_grad(func, grad, [1.5, -1.5],
...             direction='random', seed=rng)
2.9802322387695312e-08 

scipy.optimize.bracket

原文:docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.optimize.bracket.html#scipy.optimize.bracket

scipy.optimize.bracket(func, xa=0.0, xb=1.0, args=(), grow_limit=110.0, maxiter=1000)

确定函数的最小值。

给定一个函数和不同的初始点,沿着向下的方向(由初始点定义)搜索并返回三个括号内的函数最小值点。

参数:

funccallable f(x,*args)

要最小化的目标函数。

xa, xbfloat, optional

初始点。默认xa为 0.0,xb为 1.0。局部最小值不一定包含在此区间内。

argstuple, optional

附加参数(如果存在),传递给func

grow_limitfloat, optional

最大生长限制。默认为 110.0

maxiterint, optional

要执行的最大迭代次数。默认为 1000。

返回:

xa, xb, xcfloat

括号的最终点。

fa, fb, fcfloat

目标函数在括号点处的值。

funcallsint

执行的函数评估数量。

引发:

BracketError

如果在算法终止前未找到有效的括号。请参阅有效括号的条件说明。

注释

算法尝试找到三个严格排序的点(即 (x_a < x_b < x_c) 或 (x_c < x_b < x_a)),满足 (f(x_b) ≤ f(x_a)) 和 (f(x_b) ≤ f(x_c)) 的条件之一必须严格满足,所有 (x_i) 必须是有限的。

示例

此函数可以找到函数的向下凸区域:

>>> import numpy as np
>>> import matplotlib.pyplot as plt
>>> from scipy.optimize import bracket
>>> def f(x):
...     return 10*x**2 + 3*x + 5
>>> x = np.linspace(-2, 2)
>>> y = f(x)
>>> init_xa, init_xb = 0.1, 1
>>> xa, xb, xc, fa, fb, fc, funcalls = bracket(f, xa=init_xa, xb=init_xb)
>>> plt.axvline(x=init_xa, color="k", linestyle="--")
>>> plt.axvline(x=init_xb, color="k", linestyle="--")
>>> plt.plot(x, y, "-k")
>>> plt.plot(xa, fa, "bx")
>>> plt.plot(xb, fb, "rx")
>>> plt.plot(xc, fc, "bx")
>>> plt.show() 

../../_images/scipy-optimize-bracket-1_00_00.png

请注意,初始点都在最小值的右侧,并且第三个点是在“向下”的方向找到的:函数看起来在减少的方向(向左)。最终点是严格排序的,中间点的函数值小于端点的函数值;因此,最小值必须位于括号内。

scipy.optimize.line_search

原文:docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.optimize.line_search.html#scipy.optimize.line_search

scipy.optimize.line_search(f, myfprime, xk, pk, gfk=None, old_fval=None, old_old_fval=None, args=(), c1=0.0001, c2=0.9, amax=None, extra_condition=None, maxiter=10)

找到满足强 Wolfe 条件的 alpha。

参数:

fcallable f(x,*args)

目标函数。

myfprimecallable f’(x,*args)

目标函数梯度。

xkndarray

起始点。

pkndarray

搜索方向。搜索方向必须是算法收敛的下降方向。

gfkndarray,可选

x=xk 处的梯度值(xk 为当前参数估计)。如果省略,则将重新计算。

old_fvalfloat,可选

x=xk 处的函数值。如果省略,则将重新计算。

old_old_fvalfloat,可选

x=xk 之前点的函数值。

argstuple,可选

传递给目标函数的额外参数。

c1float,可选

Armijo 条件规则的参数。

c2float,可选

曲率条件规则的参数。

amaxfloat,可选

最大步长

extra_conditioncallable,可选

形如 extra_condition(alpha, x, f, g) 的可调用对象,返回布尔值。参数是建议的步长 alpha 及其相应的 xfg 值。只有在满足强 Wolfe 条件的迭代中才接受 alpha 的值。如果步长的可调用对象返回假,则算法将继续进行新的迭代。只有在满足强 Wolfe 条件的迭代中才会调用该可调用对象。

maxiterint,可选

执行的最大迭代次数。

返回:

alphafloat 或 None

Alpha 使得 x_new = x0 + alpha * pk,如果线搜索算法未收敛,则为 None。

fcint

执行的函数评估次数。

gcint

执行的梯度评估次数。

new_fvalfloat 或 None

新函数值 f(x_new)=f(x0+alpha*pk),如果线搜索算法未收敛,则为 None。

old_fvalfloat

旧函数值 f(x0)

new_slopefloat 或 None

在新值处沿搜索方向的局部斜率 <myfprime(x_new), pk>,如果线搜索算法未收敛,则为 None。

注意事项

使用线搜索算法来强制实施强 Wolfe 条件。参见 Wright 和 Nocedal,《Numerical Optimization》,1999 年,第 59-61 页。

搜索方向 pk 必须是下降方向(例如 -myfprime(xk))以找到满足强 Wolfe 条件的步长。如果搜索方向不是下降方向(例如 myfprime(xk)),则 alphanew_fvalnew_slope 将为 None。

示例

>>> import numpy as np
>>> from scipy.optimize import line_search 

定义了一个目标函数及其梯度。

>>> def obj_func(x):
...     return (x[0])**2+(x[1])**2
>>> def obj_grad(x):
...     return [2*x[0], 2*x[1]] 

我们可以找到满足强 Wolfe 条件的 alpha。

>>> start_point = np.array([1.8, 1.7])
>>> search_gradient = np.array([-1.0, -1.0])
>>> line_search(obj_func, obj_grad, start_point, search_gradient)
(1.0, 2, 1, 1.1300000000000001, 6.13, [1.6, 1.4]) 

scipy.optimize.LbfgsInvHessProduct

原文链接:docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.optimize.LbfgsInvHessProduct.html#scipy.optimize.LbfgsInvHessProduct

class scipy.optimize.LbfgsInvHessProduct(*args, **kwargs)

L-BFGS 近似逆海森线性操作器。

该操作器使用 L-BFGS 有限存储逆海森近似,在优化过程中累积的目标函数海森逆的向量与向量的乘积。

本类对象实现了scipy.sparse.linalg.LinearOperator接口。

参数:

skarray_like, shape=(n_corr, n)

n_corr最近的解向量更新数组(见[1])。

ykarray_like, shape=(n_corr, n)

n_corr最近的梯度更新数组(见[1])。

参考文献

[1]

Nocedal, Jorge. “使用有限存储更新拟牛顿矩阵。” 计算数学 35.151 (1980): 773-782.

属性:

H

共轭转置。

T

转置此线性操作器。

方法:

__call__(x)作为函数调用自身。
adjoint()共轭转置。
dot(x)矩阵-矩阵或矩阵-向量乘法。
matmat(X)矩阵-矩阵乘法。
matvec(x)矩阵-向量乘法。
rmatmat(X)共轭矩阵-矩阵乘法。
rmatvec(x)共轭矩阵-向量乘法。
todense()返回此操作器的密集数组表示。
transpose()转置这个线性操作符。
mul

scipy.optimize.HessianUpdateStrategy

原文链接:docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.optimize.HessianUpdateStrategy.html#scipy.optimize.HessianUpdateStrategy

class scipy.optimize.HessianUpdateStrategy

实现 Hessian 更新策略的接口。

许多优化方法使用 Hessian(或逆 Hessian)的近似值,如拟牛顿方法 BFGS、SR1、L-BFGS。然而,其中一些近似方法实际上不需要存储整个矩阵,或者可以以非常高效的方式计算内部矩阵与给定向量的乘积。这个类作为优化算法和拟牛顿更新策略之间的抽象接口,允许以尽可能高效的方式存储和更新内部矩阵的实现自由。不同的初始化和更新过程选择会导致不同的拟牛顿策略。

派生类应实现四种方法:initializeupdatedotget_matrix

注意事项

实现此接口的任何类的实例,都可以被方法 minimize 接受,并由兼容的求解器使用,以近似优化算法使用的 Hessian(或逆 Hessian)。

方法

dot(p)计算内部矩阵与给定向量的乘积。
get_matrix()返回当前内部矩阵。
initialize(n, approx_type)初始化内部矩阵。
update(delta_x, delta_grad)更新内部矩阵。

scipy.optimize.rosen

原文:docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.optimize.rosen.html#scipy.optimize.rosen

scipy.optimize.rosen(x)

Rosenbrock 函数。

计算的函数是:

sum(100.0*(x[1:] - x[:-1]**2.0)**2.0 + (1 - x[:-1])**2.0) 

参数:

xarray_like

要计算 Rosenbrock 函数的点的 1-D 数组。

返回:

ffloat

Rosenbrock 函数的值。

另请参见

rosen_der, rosen_hess, rosen_hess_prod

示例

>>> import numpy as np
>>> from scipy.optimize import rosen
>>> X = 0.1 * np.arange(10)
>>> rosen(X)
76.56 

对于高维输入,rosen 进行了广播。在下面的示例中,我们使用这一点来绘制二维景观。请注意,rosen_hess 不会以这种方式进行广播。

>>> import matplotlib.pyplot as plt
>>> from mpl_toolkits.mplot3d import Axes3D
>>> x = np.linspace(-1, 1, 50)
>>> X, Y = np.meshgrid(x, x)
>>> ax = plt.subplot(111, projection='3d')
>>> ax.plot_surface(X, Y, rosen([X, Y]))
>>> plt.show() 

../../_images/scipy-optimize-rosen-1.png

scipy.optimize.rosen_der

原文链接:docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.optimize.rosen_der.html#scipy.optimize.rosen_der

scipy.optimize.rosen_der(x)

Rosenbrock 函数的导数(即梯度)。

参数:

xarray_like

1-D 数组,用于计算导数的点。

返回值:

rosen_der(N,) ndarray

Rosenbrock 函数在 x 处的梯度。

另请参见:

rosen, rosen_hess, rosen_hess_prod

示例:

>>> import numpy as np
>>> from scipy.optimize import rosen_der
>>> X = 0.1 * np.arange(9)
>>> rosen_der(X)
array([ -2\. ,  10.6,  15.6,  13.4,   6.4,  -3\. , -12.4, -19.4,  62\. ]) 

scipy.optimize.rosen_hess

原文:docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.optimize.rosen_hess.html#scipy.optimize.rosen_hess

scipy.optimize.rosen_hess(x)

Rosenbrock 函数的黑塞矩阵。

参数:

xarray_like

要计算黑塞矩阵的点的一维数组。

返回值:

rosen_hessndarray

Rosenbrock 函数在 x 处的黑塞矩阵。

参见

rosen, rosen_der, rosen_hess_prod

示例

>>> import numpy as np
>>> from scipy.optimize import rosen_hess
>>> X = 0.1 * np.arange(4)
>>> rosen_hess(X)
array([[-38.,   0.,   0.,   0.],
 [  0., 134., -40.,   0.],
 [  0., -40., 130., -80.],
 [  0.,   0., -80., 200.]]) 

scipy.optimize.rosen_hess_prod

原文:docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.optimize.rosen_hess_prod.html#scipy.optimize.rosen_hess_prod

scipy.optimize.rosen_hess_prod(x, p)

Rosenbrock 函数的 Hessian 矩阵与向量的乘积。

参数:

x 数组样式

1-D 点数组,其中将计算 Hessian 矩阵。

p 数组样式

1-D 数组,将与 Hessian 矩阵相乘的向量。

返回:

rosen_hess_prod ndarray

x 处的 Rosenbrock 函数的 Hessian 矩阵与向量 p 的乘积。

另请参阅

rosen, rosen_der, rosen_hess

示例

>>> import numpy as np
>>> from scipy.optimize import rosen_hess_prod
>>> X = 0.1 * np.arange(9)
>>> p = 0.5 * np.arange(9)
>>> rosen_hess_prod(X, p)
array([  -0.,   27.,  -10.,  -95., -192., -265., -278., -195., -180.]) 

scipy.optimize.fmin

原文链接:docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.optimize.fmin.html#scipy.optimize.fmin

scipy.optimize.fmin(func, x0, args=(), xtol=0.0001, ftol=0.0001, maxiter=None, maxfun=None, full_output=0, disp=1, retall=0, callback=None, initial_simplex=None)

使用下山单纯形算法最小化函数。

该算法仅使用函数值,不使用导数或二阶导数。

参数:

funccallable func(x,*args)

要最小化的目标函数。

x0ndarray

初始猜测。

argstuple,可选

传递给 func 的额外参数,即f(x,*args)

xtolfloat,可选

在迭代之间可接受的 xopt 中的绝对误差,以收敛为目标。

ftolnumber,可选

在迭代之间 func(xopt)的绝对误差,以收敛为目标。

maxiterint,可选

执行的最大迭代次数。

maxfunnumber,可选

最大函数评估次数。

full_outputbool,可选

如果需要 fopt 和 warnflag 输出,则设置为 True。

dispbool,可选

设置为 True 以打印收敛消息。

retallbool, 可选

设置为 True 以返回每次迭代的解列表。

callbackcallable,可选

在每次迭代后调用,作为 callback(xk),其中 xk 为当前的参数向量。

initial_simplexarray_like,形状为(N + 1, N),可选

初始单纯形。如果提供,则覆盖x0initial_simplex[j,:]应包含单纯形中第 j 个顶点的 N+1 个顶点的坐标,其中 N 是维度。

返回:

xoptndarray

最小化函数的参数。

foptfloat

函数在最小值处的值:fopt = func(xopt)

iterint

执行的迭代次数。

funcallsint

执行的函数调用次数。

warnflagint

1:执行的最大函数评估次数。2:达到的最大迭代次数。

allvecslist

每次迭代的解。

另见

minimize

多元函数最小化算法接口。特别参见‘Nelder-Mead’ 方法

注意

使用 Nelder-Mead 单纯形算法寻找一个或多个变量函数的最小值。

该算法在应用中有着悠久的成功历史。但通常比使用一阶或二阶导数信息的算法慢。在实践中,它在高维问题中表现不佳,并且不适用于最小化复杂函数。此外,目前没有完整的理论描述算法何时会成功收敛到最小值,或者如果成功收敛,收敛速度如何。必须同时满足 ftol 和 xtol 标准以实现收敛。

参考文献

[1]

Nelder, J.A. 和 Mead, R. (1965), “A simplex method for function minimization”, The Computer Journal, 7, pp. 308-313

[2]

Wright, M.H. (1996), “Direct Search Methods: Once Scorned, Now Respectable”, in Numerical Analysis 1995, Proceedings of the 1995 Dundee Biennial Conference in Numerical Analysis, D.F. Griffiths and G.A. Watson (Eds.), Addison Wesley Longman, Harlow, UK, pp. 191-208.

示例

>>> def f(x):
...     return x**2 
>>> from scipy import optimize 
>>> minimum = optimize.fmin(f, 1)
Optimization terminated successfully.
 Current function value: 0.000000
 Iterations: 17
 Function evaluations: 34
>>> minimum[0]
-8.8817841970012523e-16 

scipy.optimize.fmin_powell

原文:docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.optimize.fmin_powell.html#scipy.optimize.fmin_powell

scipy.optimize.fmin_powell(func, x0, args=(), xtol=0.0001, ftol=0.0001, maxiter=None, maxfun=None, full_output=0, disp=1, retall=0, callback=None, direc=None)

使用修改后的 Powell 方法最小化函数。

此方法仅使用函数值,不使用导数。

参数:

func可调用函数 f(x,*args)

要最小化的目标函数。

x0数组

初始猜测。

args元组,可选

传递给 func 的额外参数。

xtol浮点数,可选

线搜索错误容忍度。

ftol浮点数,可选

func(xopt) 的相对误差,用于收敛。

maxiter整数,可选

执行的最大迭代次数。

maxfun整数,可选

要执行的最大函数评估次数。

full_output布尔值,可选

如果为 True,则返回 foptxidireciterfuncallswarnflag

disp布尔值,可选

如果为 True,则打印收敛信息。

retall布尔值,可选

如果为 True,则返回每次迭代的解列表。

callback可调用,可选

可选的用户提供的函数,在每次迭代后调用。调用方式为 callback(xk),其中 xk 是当前的参数向量。

direc数组,可选

初始拟合步骤和参数顺序设置为 (N, N) 数组,其中 N 是 x0 中拟合参数的数量。默认步长为 1.0,同时拟合所有参数 (np.eye((N, N)))。若要防止初始考虑步骤中的值或更改初始步长,请将其设置为 0 或所需步长在第 M 块的第 J 位置,其中 J 是 x0 中的位置,M 是所需的评估步骤,步骤将按索引顺序进行评估。随着最小化的进行,步长和顺序将自由变化。

返回:

xopt数组

最小化 func 的参数。

fopt数字

在最小值处函数的值:fopt = func(xopt)

direc数组

当前的方向设置。

iter整数

迭代次数。

funcalls整数

执行的函数调用次数。

warnflag整数

整数警告标志:

1:最大函数评估次数。2:最大迭代次数。3:遇到 NaN 结果。4:结果超出提供的边界。

allvecs列表

每次迭代的解列表。

另请参见

minimize

用于多元函数的无约束最小化算法的接口。特别查看‘Powell’方法。

注意事项

使用修改后的 Powell 方法找到 N 个变量的函数的最小值。Powell 方法是一种共轭方向方法。

该算法有两个循环。外部循环仅在内部循环上迭代。内部循环在方向集合中每个当前方向上进行最小化。在内部循环结束时,如果满足某些条件,则舍弃给出最大减少的方向,并用当前估计的 x 与内部循环开始时的估计 x 之间的差异替换。

替换最大增量方向的技术条件是检查

  1. 从该迭代中最大增量方向上无法再获得进一步的增益。

  2. 最大增量方向占内部循环迭代中函数值减少的大部分。

参考文献

Powell M.J.D. (1964) 一种在不计算导数的情况下找到多变量函数最小值的高效方法,计算机学报,7 (2):155-162。

Press W., Teukolsky S.A., Vetterling W.T., and Flannery B.P.: 数值计算方法(任何版本),剑桥大学出版社

示例

>>> def f(x):
...     return x**2 
>>> from scipy import optimize 
>>> minimum = optimize.fmin_powell(f, -1)
Optimization terminated successfully.
 Current function value: 0.000000
 Iterations: 2
 Function evaluations: 16
>>> minimum
array(0.0) 

scipy.optimize.fmin_cg

原文链接:docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.optimize.fmin_cg.html#scipy.optimize.fmin_cg

scipy.optimize.fmin_cg(f, x0, fprime=None, args=(), gtol=1e-05, norm=inf, epsilon=1.4901161193847656e-08, maxiter=None, full_output=0, disp=1, retall=0, callback=None, c1=0.0001, c2=0.4)

使用非线性共轭梯度算法最小化函数。

参数:

fcallable,f(x, *args)

要最小化的目标函数。这里x必须是要在搜索最小值时更改的变量的 1-D 数组,argsf的其他(固定)参数。

x0ndarray

xopt的用户提供的初始估计值,即x的最优值。必须是值的 1-D 数组。

fprimecallable,fprime(x, *args),可选

返回fx处的梯度的函数。这里xargs如上所述为f。返回的值必须是 1-D 数组。默认为 None,此时数值上近似梯度(见下面的epsilon)。

argstuple,可选

传递给ffprime的参数值。每当需要额外的固定参数完全指定ffprime函数时,必须提供。

gtolfloat,可选

当梯度的范数小于gtol时停止。

normfloat,可选

用于梯度范数的顺序(-np.inf是最小值,np.inf是最大值)。

epsilonfloat 或 ndarray,可选

fprime被数值近似时使用的步长。可以是标量或 1-D 数组。默认为sqrt(eps),其中 eps 是浮点数机器精度。通常sqrt(eps)约为 1.5e-8。

maxiterint,可选

要执行的最大迭代次数。默认为200 * len(x0)

full_outputbool,可选

如果为 True,则除了xopt之外,还返回foptfunc_callsgrad_callswarnflag。有关可选返回值的详细信息,请参见下面的 Returns 部分。

dispbool,可选

如果为 True,则返回一个收敛消息,然后是xopt

retallbool,可选

如果为 True,则将每次迭代的结果添加到返回值中。

callbackcallable,可选

一个可选的用户提供的函数,在每次迭代后调用。以callback(xk)的形式调用,其中xkx0的当前值。

c1float,默认值:1e-4

Armijo 条件规则的参数。

c2float,默认值:0.4

曲率条件规则的参数。

返回:

xoptndarray

最小化 f 的参数,即f(xopt) == fopt

foptfloat,可选

找到的最小值,f(xopt)。仅当full_output为 True 时返回。

func_callsint,可选

进行的函数调用次数。仅当full_output为 True 时返回。

grad_callsint,可选

进行的梯度调用次数。仅当full_output为 True 时返回。

warnflagint,可选

警告状态的整数值,仅当full_output为 True 时返回。

0:成功。

1:超过了最大迭代次数。

2:梯度和/或函数调用未更改。可能表示

即精度丢失,即例程未收敛。

3:遇到 NaN 结果。

allvecs 是一个 ndarray 的列表,可选

数组列表,包含每次迭代的结果。仅在 retall 为 True 时返回。

另请参见

minimize

scipy.optimize 的所有算法,无论是多变量函数的无约束还是有约束最小化,都有一个共同的接口。它提供了一种通过指定 method='CG' 来调用 fmin_cg 的替代方式。

注意事项

此共轭梯度算法基于 Polak 和 Ribiere 的算法 [1]

共轭梯度方法在以下情况下表现更好:

  1. f 有一个唯一的全局最小点,并且没有局部最小值或其他静止点,

  2. f 至少在局部范围内可以被变量的二次函数合理逼近,

  3. f 是连续的,并且具有连续的梯度,

  4. fprime 不应过大,例如其范数应小于 1000,

  5. 初始猜测 x0 应该足够接近 f 的全局最小点 xopt

参数 c1c2 必须满足 0 < c1 < c2 < 1

参考文献

[1]

Wright & Nocedal,《数值优化》,1999 年,第 120-122 页。

示例

示例 1:寻找给定参数值和初始猜测 (u, v) = (0, 0) 下表达式 a*u**2 + b*u*v + c*v**2 + d*u + e*v + f 的最小值。

>>> import numpy as np
>>> args = (2, 3, 7, 8, 9, 10)  # parameter values
>>> def f(x, *args):
...     u, v = x
...     a, b, c, d, e, f = args
...     return a*u**2 + b*u*v + c*v**2 + d*u + e*v + f
>>> def gradf(x, *args):
...     u, v = x
...     a, b, c, d, e, f = args
...     gu = 2*a*u + b*v + d     # u-component of the gradient
...     gv = b*u + 2*c*v + e     # v-component of the gradient
...     return np.asarray((gu, gv))
>>> x0 = np.asarray((0, 0))  # Initial guess.
>>> from scipy import optimize
>>> res1 = optimize.fmin_cg(f, x0, fprime=gradf, args=args)
Optimization terminated successfully.
 Current function value: 1.617021
 Iterations: 4
 Function evaluations: 8
 Gradient evaluations: 8
>>> res1
array([-1.80851064, -0.25531915]) 

示例 2:使用 minimize 函数解决相同问题。(myopts 字典显示所有可用选项,实际应用中通常只需要非默认值。返回值将是一个字典。)

>>> opts = {'maxiter' : None,    # default value.
...         'disp' : True,    # non-default value.
...         'gtol' : 1e-5,    # default value.
...         'norm' : np.inf,  # default value.
...         'eps' : 1.4901161193847656e-08}  # default value.
>>> res2 = optimize.minimize(f, x0, jac=gradf, args=args,
...                          method='CG', options=opts)
Optimization terminated successfully.
 Current function value: 1.617021
 Iterations: 4
 Function evaluations: 8
 Gradient evaluations: 8
>>> res2.x  # minimum found
array([-1.80851064, -0.25531915]) 

scipy.optimize.fmin_bfgs

原文:docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.optimize.fmin_bfgs.html#scipy.optimize.fmin_bfgs

scipy.optimize.fmin_bfgs(f, x0, fprime=None, args=(), gtol=1e-05, norm=inf, epsilon=1.4901161193847656e-08, maxiter=None, full_output=0, disp=1, retall=0, callback=None, xrtol=0, c1=0.0001, c2=0.9, hess_inv0=None)

使用 BFGS 算法最小化函数。

参数:

f可调用函数 f(x,*args)

要最小化的目标函数。

x0ndarray

初始猜测,形状为 (n,)

fprime可调用函数 f'(x,*args),可选

f 的梯度。

args元组,可选

传递给 f 和 fprime 的额外参数。

gtol浮点数,可选

如果梯度范数小于 gtol,则成功终止。

norm浮点数,可选

范数的顺序(Inf 为最大,-Inf 为最小)

epsilon整数或 ndarray,可选

如果 fprime 是近似的,则使用此值作为步长。

callback可调用对象,可选

每次迭代后调用的可选用户提供的函数。调用方式为 callback(xk),其中 xk 是当前的参数向量。

maxiter整数,可选

要执行的最大迭代次数。

full_output布尔值,可选

如果为 True,则除了 xopt 外还返回 foptfunc_callsgrad_callswarnflag

disp布尔值,可选

如果为 True,则打印收敛消息。

retall布尔值,可选

如果为 True,则返回每次迭代的结果列表。

xrtol浮点数,默认值:0

x 的相对容差。如果步长小于 xk * xrtol,其中 xk 是当前的参数向量,则成功终止。

c1浮点数,默认值:1e-4

用于 Armijo 条件规则的参数。

c2浮点数,默认值:0.9

曲率条件规则的参数。

hess_inv0None 或 ndarray,可选``

初始逆海森估计,形状为 (n, n)。如果为 None(默认),则使用单位矩阵。

返回:

xoptndarray

最小化函数 f 的参数,即 f(xopt) == fopt

fopt浮点数

最小值。

goptndarray

最小值处的梯度值,即 f’(xopt),应接近 0。

Boptndarray

f’’(xopt) 的倒数值,即逆海森矩阵。

func_calls整数

函数调用数。

grad_calls整数

进行的梯度调用数。

warnflag整数

1:超过最大迭代次数。2:梯度和/或函数调用未更改。3:遇到 NaN 结果。

allvecs列表

xopt 在每次迭代时的值。仅在 retall 为 True 时返回。

另请参见

最小化

多变量函数最小化算法的接口。特别是看 method='BFGS'

注意

优化函数 f,其梯度由 fprime 给出,使用 Broyden、Fletcher、Goldfarb 和 Shanno(BFGS)的拟牛顿方法。

参数 c1c2 必须满足 0 < c1 < c2 < 1

参考

Wright 和 Nocedal,《数值优化》,1999 年,第 198 页。

示例

>>> import numpy as np
>>> from scipy.optimize import fmin_bfgs
>>> def quadratic_cost(x, Q):
...     return x @ Q @ x
...
>>> x0 = np.array([-3, -4])
>>> cost_weight =  np.diag([1., 10.])
>>> # Note that a trailing comma is necessary for a tuple with single element
>>> fmin_bfgs(quadratic_cost, x0, args=(cost_weight,))
Optimization terminated successfully.
 Current function value: 0.000000
 Iterations: 7                   # may vary
 Function evaluations: 24        # may vary
 Gradient evaluations: 8         # may vary
array([ 2.85169950e-06, -4.61820139e-07]) 
>>> def quadratic_cost_grad(x, Q):
...     return 2 * Q @ x
...
>>> fmin_bfgs(quadratic_cost, x0, quadratic_cost_grad, args=(cost_weight,))
Optimization terminated successfully.
 Current function value: 0.000000
 Iterations: 7
 Function evaluations: 8
 Gradient evaluations: 8
array([ 2.85916637e-06, -4.54371951e-07]) 

scipy.optimize.fmin_ncg

原文:docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.optimize.fmin_ncg.html#scipy.optimize.fmin_ncg

scipy.optimize.fmin_ncg(f, x0, fprime, fhess_p=None, fhess=None, args=(), avextol=1e-05, epsilon=1.4901161193847656e-08, maxiter=None, full_output=0, disp=1, retall=0, callback=None, c1=0.0001, c2=0.9)

使用 Newton-CG 方法进行无约束函数最小化。

参数:

fcallable f(x, *args)

要最小化的目标函数。

x0ndarray

初始猜测。

fprimecallable f'(x, *args)

f 的梯度。

fhess_pcallable fhess_p(x, p, *args), optional

计算 f 的 Hessian 矩阵乘以任意向量 p 的函数。

fhesscallable fhess(x, *args), optional

计算 f 的 Hessian 矩阵的函数。

argstuple, optional

传递给 f、fprime、fhess_p 和 fhess 的额外参数(这些函数的所有额外参数相同)。

epsilonfloat 或 ndarray, optional

如果 fhess 是近似的,则使用此值作为步长大小。

callbackcallable, optional

每次迭代后调用的可选用户提供函数。作为 callback(xk)调用,其中 xk 是当前参数向量。

avextolfloat, optional

当最小化器中的平均相对误差低于此值时,假定收敛。

maxiterint, optional

执行的最大迭代次数。

full_outputbool, optional

如果为 True,则返回可选的输出。

dispbool, optional

如果为 True,则打印收敛消息。

retallbool, optional

如果为 True,则返回每次迭代的结果列表。

c1float,默认值:1e-4

Armijo 条件规则的参数。

c2float,默认值:0.9

曲率条件规则的参数

返回:

xoptndarray

使 f 最小化的参数,即f(xopt) == fopt

foptfloat

函数在 xopt 处的值,即fopt = f(xopt)

fcallsint

调用的函数次数。

gcallsint

调用的梯度次数。

hcallsint

调用黑塞矩阵的次数。

warnflagint

算法生成的警告。1:超过最大迭代次数。2:线搜索失败(精度丢失)。3:遇到 NaN 结果。

allvecslist

每次迭代的结果,如果 retall 为 True(见下文)。

另请参阅

minimize

用于多元函数最小化算法的接口。特别查看‘Newton-CG’method

注意事项

只需给出fhess_pfhess中的一个。如果提供了fhess,则将忽略fhess_p。如果未提供fhessfhess_p,则将使用fprime上的有限差分近似计算 Hessian 乘积。fhess_p必须计算任意向量的 Hessian 乘积。如果未给出,将使用fprime上的有限差分计算它。

Newton-CG 方法也称为截断 Newton 方法。此函数与 scipy.optimize.fmin_tnc 不同,因为

  1. scipy.optimize.fmin_ncg 是纯用 Python 和 NumPy 编写的。

    scipy 同时调用了 scipy.optimize.fmin_tnc 来调用一个 C 函数。

  2. scipy.optimize.fmin_ncg 仅适用于无约束最小化。

    scipy.optimize.fmin_tnc 则适用于无约束最小化或者箱约束最小化。(箱约束为每个变量分别给出下限和上限。)

参数 c1c2 必须满足 0 < c1 < c2 < 1

参考文献

Wright & Nocedal,《数值优化》,1999 年,第 140 页。