目标函数极值求解的几种方法题目:分别用最速下降法,牛顿法,共轭梯度法,拟牛顿法求函数24232221)5(5)1()5(5)1(-+-+-+-=x x x x f 的最小值,初始点自拟。
一维搜索法:迭代下降算法大都具有一个共同点,这就是得到点()k x 后需要按某种规则确定一个方向()k d ,再从()k x 出发,沿方向()k d 在直线(或射线)上求目标函数的极小点,从而得到()k x 的后继点()1+k x ,重复以上做法,直至求得问题的解,这里所谓求目标函数在直线上的极小点,称为一维搜索。
一维搜索的方法很多,归纳起来大体可以分为两类,一类是试探法:采用这类方法,需要按某种方式找试探点,通过一系列的试探点来确定极小点。
另一类是函数逼近法或插值法:这类方法是用某种较简单的曲线逼近本来的函数曲线,通过求逼近函数的极小点来估计目标函数的极小点。
这里采用的是第一类试探法中的黄金分割法。
实现过程如下:⑴ 置初始区间[11,b a ]及精度要求L>0,计算试探点1λ和1μ,计算函数值()1λf 和()1μf ,计算公式是:()1111382.0a b a -+=λ,()1111618.0a b a -+=μ。
令k=1。
⑵ 若La b k k <-则停止计算。
否则,当()K f λ>()k f μ时,转步骤⑶;当()K f λ≤()k f μ时,转步骤⑷ 。
⑶ 置kk a λ=+1,kk b b =+1,kk μλ=+1,()1111618.0++++-+=k k k k a b a μ,计算函数值()1+k f μ,转⑸。
⑷ 置kk a a =+1,kk b μ=+1,kk μμ=+1,()1111382.0++++-+=k k k k a b a λ,计算函数值()1+k f λ,转⑸。
最速下降法实现原理描述:在求目标函数极小值问题时,总希望从一点出发,选择一个目标函数值下降最快的方向,以利于尽快达到极小点,正是基于这样一种愿望提出的最速下降法,并且经过一系列理论推导研究可知,负梯度方向为最速下降方向。
最速下降法的迭代公式是()()()k k k k d x x λ+=+1,其中()k d 是从()k x 出发的搜索方向,这里取在点()k x 处最速下降方向,即()()k k x f d -∇=。
k λ是从()k x 出发沿方向()k d 进行的一维搜索步长,满足()()()()()()k k k k k d x f d x f λλλ+=+≥0min 。
实现步骤如下:⑴ 给定初点()n R x ∈1 ,允许误差0>ε,置k=1。
⑵ 计算搜索方向()()k k x f d -∇=, 若()ε≤k d ,则停止计算;否则,从()k x 出发,沿方向()k d 进行的一维搜索,求k λ,使()()()()()()k k k k k d x f d x f λλλ+=+≥0mi n 。
⑶ ()()()k k k k d x x λ+=+1,置k=k+1返回步骤 ⑵。
牛顿法牛顿法迭代公式:()()()k k k k d x x λ+=+1,()k d 是在点()k x 处的牛顿方向,()()()()()k k k xf xf d∇-∇=-12,kλ是从()k x 出发沿牛顿方向()k d 进行搜索的最优步长。
⑴ 给定初点()n R x ∈1 ,允许误差0>ε,置k=1。
⑵ 计算()()k k x f g ∇=, 若()ε≤k g ,则停止计算;否则,转⑶。
⑶ 计算()()()k k k g x f d 12--∇=,从()k x 出发,沿方向()k d 进行的一维搜索,求k λ,使()()()()()()k k k k k d x f d x f λλλ+=+≥0min ,()()()k k k k d x x λ+=+1,置k=k+1返回步骤 ⑵。
共轭梯度法若()()()k d d d ,,,21 是n R 中k 个方向,它们两两关于A 共轭,即满足()()kj i j i Addj Ti ,,1,;,0 =≠=,称这组方向为A 的k 个共轭方向。
共轭梯度法的基本思想是把共轭性与最速下降法相结合,利用已知点处的梯度构造一组共轭方向,并沿这组方向进行搜索,求出目标函数的极小点,根据共轭方向的基本性质这种方法具有二次终止性。
实现步骤如下:⑴ 给定初点()n R x ∈1 ,允许误差0>ε; ⑵ 若ε≤∇)(1x f ,则停止计算;否则,转⑶; ⑶ 置()()()11x f d -∇=,k=1。
⑷ 作一维搜索,求k λ,满足()()()()()()k k k k k d x f d x f λλλ+=+≥0min ;⑸ 令()()()k k k k d x x λ+=+1,求()()()11++∇=k k x f g 。
⑹ 若()ε≤+1k g ,则停止计算;否则,转⑺; ⑺ 若k=n,则令()()11+=n x x ,转⑶;否则,转8);⑻ 令()()k k k k d g d β+-=++)1(1,其中()()()()221k k k xg xg +=β,置k=k+1,转⑷。
程序#include<stdio.h> #include<math.h> #include<iostream.h>#define N 100double F(double x[],double p[],double xi[],double ba[],int n,double t) { double f=0; int i;for(i=0;i<n;i++)f=f+xi[i]*(x[i]+t*p[i]-ba[i])*(x[i]+t*p[i]-ba[i]); return f;}double HJFC(double x[],double p[],double xi[],double ba[],int n) {double a=0,b=10,x1,x2,f1,f2,e=0.0001,y; x2=a+0.618*(b-a); f2=F(x,p,xi,ba,n,x2); x1=a+0.382*(b-a); f1=F(x,p,xi,ba,n,x1);while(fabs(b-a)>e){if(f1<f2){b=x2;x2=x1;f2=f1;x1=a+0.382*(b-a);f1=F(x,p,xi,ba,n,x1);}else if(f1==f2){a=x1;b=x2;x2=a+0.618*(b-a);f2=F(x,p,xi,ba,n,x2);x1=a+0.382*(b-a);f1=F(x,p,xi,ba,n,x1);}else{a=x1;x1=x2;f1=f2;x2=a+0.618*(b-a);f2=F(x,p,xi,ba,n,x2);}}y=0.5*(b+a);return y;}void zuisu(double x[],double xi[],double ba[],int n) {int i,k=1;double sum,eps,arph,g[N],p[N];eps=0.000001;sum=0;for(i=0;i<n;i++){g[i]=2*xi[i]*(x[i]-ba[i]);p[i]=-g[i];sum=sum+p[i]*p[i];}i=0;while(sqrt(sum)>eps&&i<N){sum=0;arph=HJFC(x,p,xi,ba,n);for(i=0;i<n;i++){x[i]=x[i]+arph*p[i];g[i]=2*xi[i]*(x[i]-ba[i]);p[i]=-g[i];sum=sum+p[i]*p[i];}printf("第%d次迭代:\n\n",k);printf("步长lambda=%f\n",arph);for(i=0;i<n;i++)printf("x[%d]=%f\t",i,x[i]);printf("\n\n");k++;}printf("最后结果为:\n");for(i=0;i<n;i++)printf("x[%d]=%f\n",i,x[i]);}void gonge(double x[],double xi[],double ba[],int n) {int k=1,i;double sum1,sum2,eps,bita,arph,g[N],p[N];eps=0.000001;sum1=0;for(i=0;i<n;i++){g[i]=2*xi[i]*(x[i]-ba[i]);sum1+=g[i]*g[i];}while((sqrt(sum1)>eps)&&(k<N)){if(k==1){for(i=0;i<n;i++)p[i]=-g[i];bita=0;}else{bita=sum1/sum2;for(i=0;i<n;i++)p[i]=-g[i]+bita*p[i];}arph=HJFC(x,p,xi,ba,n);sum1=0;sum2=0;for(i=0;i<n;i++){x[i]=x[i]+arph*p[i];g[n+i]=g[i];g[i]=2*xi[i]*(x[i]-ba[i]);sum1+=g[i]*g[i];sum2+=g[n+i]*g[n+i];}printf("第%d次迭代:\n\n",k);printf("步长lambda=%f\t",arph);printf("bita=%f\t\n",bita);for(i=0;i<n;i++)printf("x[%d]=%f\t",i,x[i]);printf("\n\n");k++;}printf("最后结果为:\n");for(i=0;i<n;i++)printf("x[%d]=%f\n",i,x[i]);}void niudun(double x[],double xi[],double ba[],int n) {int k=1,i,j;double sum,eps,arph,g[N],p[N],h[N][N];eps=0.000001;sum=0;for(i=0;i<n;i++){g[i]=2*xi[i]*(x[i]-ba[i]);sum+=g[i]*g[i];}printf("过程\n\n");while((sqrt(sum)>eps)&&(k<N)){for(i=0;i<n;i++)for(j=0;j<n;j++)if(i==j)h[i][j]=-1/(2*xi[i]);elseh[i][j]=0;for(i=0;i<n;i++)p[i]=0;for(i=0;i<n;i++)for(j=0;j<n;j++)p[i]=p[i]+h[i][j]*g[j];arph=HJFC(x,p,xi,ba,n);sum=0;for(i=0;i<n;i++){x[i]=x[i]+arph*p[i];g[i]=2*xi[i]*(x[i]-ba[i]);sum+=g[i]*g[i];}printf("第%d次迭代:\n\n",k);printf("步长lambda=%f\n",arph);for(i=0;i<n;i++)printf("x[%d]=%f\t",i,x[i]);printf("\n\n");k++;}printf("最后结果为:\n");for(i=0;i<n;i++)printf("x[%d]=%f\n",i,x[i]);}void main(){int i,n;double x[N],xi[N],ba[N];printf("请输入函数的元数:");scanf("%d",&n);printf("请输入函数的系数:");for(i=0;i<n;i++)scanf("%lf",&xi[i]);printf("请输入ba[i]的值:");for(i=0;i<n;i++)scanf("%lf",&ba[i]);printf("请输入初始值:\n");for(i=0;i<n;i++)scanf("%lf",&x[i]);/* printf("最速下降法迭代过程:\n");zuisu(x,xi,ba,n);*//* printf("牛顿法迭代过程:\n");niudun(x,xi,ba,n);*/printf("共轭梯度法迭代过程:\n");gonge(x,xi,ba,n);}。