×

最速下降

最速下降法推导中有个公式,在如下图片中,它是怎么用泰勒公式推导的,还有符号o代表什么意思?牛顿法为什么比最速下降法好

admin admin 发表于2022-05-12 22:29:02 浏览127 评论0

抢沙发发表评论

最速下降法推导中有个公式,在如下图片中,它是怎么用泰勒公式推导的,还有符号o代表什么意思

f(x)一般是势能函数(不是向量),x是个n维向量(x1,x2,...,xn),f(x)的梯度是个n维向量,定义是 (df/dx1,df/dx2,...,df/dxn),泰勒展开的一阶,就是f(x+dx)=f(x) + (df/dx1,df/dx2,...,df/dxn)’ (dx1,dx2,...,dxn) + 二阶偏导矩阵*二阶小量,反正后面的那些项,就越来越小了。有点类似一元的情况,f(x+dx)=f(x)+f’(x)*dx+f’’(x)/2!*x^2....,只是换成了n维向量罢了,泰勒级数的精神是不变的。A=o(B)代表的是A比起B是无穷小(当t趋近于0的时候),就是说商A/B趋近于0。比如说,t是o(1),因为t/1在t趋近于0的时候,极限是0。t^2是o(t),因为t^2/t=t,在t趋近于0的时候,极限是0。梯度法的原理,其实是在已知梯度向量 (df/dx1,df/dx2,...,df/dxn)的情况下,和dx1*dx1+dx2*dx2+...+dxn*dxn=定值(即下一步搜索的步长是定值)的限制条件下,如何寻找正确的搜索方向,让势函数f(x+dx)变得更小,根据泰勒展开,忽略高阶小量后,这个问题就化为了如何让 df/dx1*dx1+...df/dxn*dxn 最小。这里要用到柯西不等式,(df/dx1*dx1+...df/dxn*dxn)^2《=(df/dx1*df/dx1+...+df/dxn*df/dxn)(dx1*dx1+dx2*dx2+...+dxn*dxn)df/dx1*df/dx1+...+df/dxn*df/dxn(这个是已知量,因为一阶偏导数都已知,就是梯度)和dx1*dx1+dx2*dx2+...+dxn*dxn(这个是搜索步长的平方)都是定值。柯西不等式的等号取到,是在 (df/dx1)/dx1=...=(df/dxn)/dxn 的时候,因此下一步的搜索方向,和梯度向量是共线的,也就是说跟着梯度反着走的。梯度法的数学原理,其实是柯西不等式。

牛顿法为什么比最速下降法好

因为最速下降法的迭代点在向极小点靠近的过程中走的是曲折路线,易产生锯齿现象,导致每次迭代行进的距离变得越来越小,收敛速度不快。而如果目标函数有连续二阶偏导数,牛顿法可以快速收敛到问题的极小点

最速下降法的c语言编程,急求大神

// this program made by lusiyuan#include《stdio.h》#include《math.h》#define N 10#define eps pow(10,-6)double f(double x,double g,double t){ double s; s=pow(x-t*g,2)+4*pow(x-t*g,2); return s;}void sb(double *a,double *b,double x,double g){ double t0,t1,t,h,alpha,f0,f1; int k=0; t0=10; /*初始值*/ h=1; /*初始步长*/ alpha=2; /*加步系数*/f0=f(x,g,t0); t1=t0+h; f1=f(x,g,t1); while(1) { if(f1《f0) { h=alpha*h; t=t0; t0=t1; f0=f1; k++; } else { if(k==0) {h=-h;t=t1;} else { *a=t《t1?t:t1; *b=t》t1?t:t1; break; } } t1=t0+h; f1=f(x,g,t1); }}double hjfg(double x,double g){ double beta,t1,t2,t; double f1,f2; double a=0,b=0; double *c,*d; c=&a,d=&b sb(c,d,x,g); printf(“\n[a,b]=[%lf,%lf]“,a,b); beta=(sqrt(5)-1.0)/2; t2=a+beta*(b-a); f2=f(x,g,t2); t1=a+b-t2; f1=f(x,g,t1); while(1) { if(fabs(t1-t2)《 eps) break; else { if(f1《f2) { t=(t1+t2)/2; b=t2; t2=t1; f2=f1; t1=a+b-t2; f1=f(x,g,t1); } else { a=t1; t1=t2; f1=f2; t2=a+beta*(b-a); f2=f(x,g,t2); } } } t=(t1+t2)/2; return t;}void zsxjf(){ double x[N],g[N],t=0,f0,mod; int i,n; printf(“请输入n(为几元函数)=“); scanf(“%d“,&n); printf(“\n请输入初始值:\n“); for(i=0;i《n;i++) scanf(“%lf“,&x[i]); f0=f(x,g,t); g=2*x; g=8*x; t=hjfg(x,g); printf(“\nt=%lf“,t); while(1) {mod=sqrt(pow(g,2)+pow(g,2)); printf(“\nmod=%lf“,mod); if(mod《eps) break; else { x=x-t*g; x=x-t*g; f0=f(x,g,t); g=2*x; g=8*x; t=hjfg(x,g); } printf(“\n-----------------------------------------------“);printf(“\nt=%lf“,t); } printf(“\n最优解为:x%d=%lf,x%d=%lf“,1,x,2,x); printf(“\n函数最有值为:f=%lf“,f(x,g,t));}int main(){ zsxjf();}编译通过,这种代码很好写的。