首页 > 编程知识 正文

python多元函数求极小值,牛顿法求多元函数极值

时间:2023-05-06 11:37:11 阅读:163090 作者:2710

1 .引言

我们在初中的时候学过一元二次函数。 在求解时引入求根公式,代入公式就可以得到不同的根。 如果想计算高次方程的解,能导出求根公式吗?

伽罗瓦在群论中证实,五次以上的多项式方程没有给出表示的求根式,但在行星轨道计算等科学研究中,对求解高次方程的真正需要较多。 既然得不到明确的求根公式,我们就可以用迭代的方法逼近真实的解。

求解多项式方程的问题实际上可以看作函数求极值,如果我们是对的

的解决得到驻地,代入驻地

可以计算出函数的极值。 很明显,低阶方程的求解可以用求根公式准确计算

的值,但要解高次方程,必须使用近似的思路,如梯度下降法、最速下降法、昏迷睫毛膏法等。 本文主要讨论用昏迷睫毛膏法和python对一元函数和多元函数求极值。

2 .昏迷睫毛膏法的基本原理

2.1 .一元函数昏迷睫毛膏法

函数时

是一元函数,使用潇洒鸭公式的二次近似即可得到

一元函数取极值的条件是

、两端分别求导(下式的等号写成等号)得到

整理后拿出来

的迭代公式

进而写出迭代关系式,得到

因为昏迷睫毛膏法的迭代关系基于要求求解极值函数的导数图像的点的斜率进行迭代,所以没有步骤的概念,在什么点可以获得极值仅取决于迭代的步骤数。 相应地,迭代的次数越多越接近极值点。

在上面介绍了抽象的表达式之后,让我们来看看这样的小例子。 函数是已知的

如果没有其他限制条件的话就求出

的极值。

用昏迷睫毛膏法计算极值前,用软件绘制

的图像,用肉眼大致观测极值在哪里,有助于在后续计算中验证是否正确。

image.png

首先,需要给出初始值

这是开始迭代的位置;

然后,计算初始位置的一次微分值和二次微分值,

接着,代入迭代式

最后,得到第一次迭代的值

重复上述两个步骤得到

在、

停止条件是设定的反复步骤数。

2.2 .一元函数昏迷睫毛膏法的python程序

来自sympy import *

# step是反复步骤数,x0是初始位置,obj是要求极值的函数

DefNewtons(step,x0,obj ) :

i=1 #记录迭代次数的变量

x0=float(x0 ) #浮点数计算更快

obj_Deri=diff(obj,x )定义与上述表达式相对应的一阶导数

obj_sec_Deri=diff(obj,x,2 ) #来定义与上述公式相对应的二次导数

while i=step:

if i==1:

#第一次迭代的更新表达式

xnew=x0-(obj_Deri.subs(x,x0 )/obj_sec_deri.subs(x ) x,x0 ) )

print ('迭代第%d次: %.5f ) % (I,xnew ) ) ) ) ) ) ) ) ) )。

i=i 1

else:

#后续迭代更新表达式

xnew=xnew-(obj_Deri.subs(x,xnew )/obj_sec_deri.subs(x ) x,xnew ) )

print ('迭代第%d次: %.5f ) % (I,xnew ) ) ) ) ) ) ) ) ) )。

i=i 1

return xnew

x=symbols(x ) ) x是字符变量

result=newtons (50,10,x**6 x ) )

print ('最佳迭代位置: %.5f' %result ) ) ) ) ) ) ) ) ) )。

执行程序的结果如下。

第一次迭代: 8.00000

迭代第二次: 6.39999

反复第三次: 5.11997

迭代第四次: 4.09593

第五次迭代: 3.27662

第六次迭代:

2.62101

迭代第7次:2.09610

迭代第8次:1.67515

迭代第9次:1.33589

迭代第10次:1.05825

迭代第11次:0.82002

迭代第12次:0.58229

迭代第13次:0.17590

迭代第14次:-34.68063

迭代第15次:-27.74450

迭代第16次:-22.19560

迭代第17次:-17.75648

迭代第18次:-14.20519

迭代第19次:-11.36415

迭代第20次:-9.09132

迭代第21次:-7.27306

迭代第22次:-5.81846

迭代第23次:-4.65480

迭代第24次:-3.72391

迭代第25次:-2.97930

迭代第26次:-2.38386

迭代第27次:-1.90812

迭代第28次:-1.52901

迭代第29次:-1.22931

迭代第30次:-0.99804

迭代第31次:-0.83203

迭代第32次:-0.73518

迭代第33次:-0.70225

迭代第34次:-0.69886

迭代第35次:-0.69883

迭代第36次:-0.69883

迭代第37次:-0.69883

迭代第38次:-0.69883

迭代第39次:-0.69883

迭代第40次:-0.69883

迭代第41次:-0.69883

迭代第42次:-0.69883

迭代第43次:-0.69883

迭代第44次:-0.69883

迭代第45次:-0.69883

迭代第46次:-0.69883

迭代第47次:-0.69883

迭代第48次:-0.69883

迭代第49次:-0.69883

迭代第50次:-0.69883

最佳迭代的位置:-0.69883

Process finished with exit code 0

函数的极值点为-0.69883,与我们之前绘制的图像观测值一致。

2.3. 多元函数昏睡的睫毛膏法

多元函数用昏睡的睫毛膏法求极值的思路依然采用潇洒的小鸭子公式近似展开,只不过这里的

为向量形式,假设

为二元函数:

对上述公式两侧求梯度,令其等于零,之后再进行整理,可得迭代公式(由于涉及矩阵求导数等一系列复杂操作,此处可以粗浅的理解一下):

上述第一个公式中

表示在

点处的梯度值,

表示该点的二阶梯度也可以写成Hessian矩阵,迭代公式使用了Hessian矩阵的逆和梯度值来确定。

2.3. 多元函数昏睡的睫毛膏法的python程序

from sympy import *

import numpy as np

# 假设多元函数是二维形式

# x_init为二维向量(x1, x2)

def newton_dou(step, x_init, obj):

i = 1 # 记录迭代次数的变量

while i <= step:

if i == 1:

grandient_obj = np.array([diff(obj, x1).subs(x1, x_init[0]).subs(x2, x_init[1]), diff(obj, x2).subs(x1, x_init[0]).subs(x2, x_init[1])], dtype=float) # 初始点的梯度值

hessian_obj = np.array([[diff(obj, x1, 2), diff(diff(obj, x1), x2)], [diff(diff(obj, x2), x1), diff(obj, x2, 2)]], dtype=float) # 初始点的hessian矩阵

inverse = np.linalg.inv(hessian_obj) # hessian矩阵求逆

x_new = x_init - np.matmul(inverse, grandient_obj) # 第一次迭代公式

print(x_new)

# print('迭代第%d次:%.5f' %(i, x_new))

i = i + 1

else:

grandient_obj = np.array([diff(obj, x1).subs(x1, x_new[0]).subs(x2, x_new[1]), diff(obj, x2).subs(x1, x_new[0]).subs(x2, x_new[1])], dtype=float) # 当前点的梯度值

hessian_obj = np.array([[diff(obj, x1, 2), diff(diff(obj, x1), x2)], [diff(diff(obj, x2), x1), diff(obj, x2, 2)]], dtype=float) # 当前点的hessian矩阵

inverse = np.linalg.inv(hessian_obj) # hessian矩阵求逆

x_new = x_new - np.matmul(inverse, grandient_obj) # 迭代公式

print(x_new)

# print('迭代第%d次:%.5f' % (i, x_new))

i = i + 1

return x_new

x0 = np.array([0, 0], dtype=float)

x1 = symbols("x1")

x2 = symbols("x2")

newton_dou(5, x0, x1**2+2*x2**2-2*x1*x2-2*x2)

程序执行的结果如下:

[1. 1.]

[1. 1.]

[1. 1.]

[1. 1.]

[1. 1.]

Process finished with exit code 0

经过实际计算函数

的极值点为

,只需一次迭代就能收敛到极值点。

3. 结束语

本文只是粗浅的将昏睡的睫毛膏法的原理进行语言和程序描述,没有过多的探讨具体实施的细节,实际中机器学习等相关算法进行昏睡的睫毛膏法迭代时并非如此编程。昏睡的睫毛膏法由昏睡的睫毛膏本人发现并命名,但是sldlt早于昏睡的睫毛膏发现的46年就已经提出该算法,现在昏睡的睫毛膏法又称为昏睡的睫毛膏-sldlt方法。昏睡的睫毛膏法有很多的缺点在此并没有讨论,例如在一元函数情况时,会产生导数为零不能迭代的情况或者迭代点有震荡往复等情况出现;多元函数的hessian矩阵计算困难,收敛过慢等情况,因此又产生了拟昏睡的睫毛膏法和阻尼昏睡的睫毛膏法等改进的方法,想进一步学习的读者可以参考非线性优化领域的相关书籍。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。