工程优化目标函数的几种极值求解方法c++编程

更新时间:2024-04-23 23:05:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

目标函数极值求解的几种方法

题目:分别用最速下降法,牛顿法,共轭梯度法,拟牛顿法求函数

f?(x1?1)?5(x2?5)?(x3?1)?5(x4?5)2222的最小值,初始点自拟。

一维搜索法:

迭代下降算法大都具有一个共同点,这就是得到点x?k?后需要按某种规则确定一个方向d?k?,再从x?k?出发,沿方向d?k?在直线(或射线)上求目标函数的极小点,从而得到x?k?的后继点x?k?1?,重复以上做法,直至求得问题的解,这里所谓求目标函数在直线上的极小点,称为一维搜索。

一维搜索的方法很多,归纳起来大体可以分为两类,一类是试探法:采用这类方法,需要按某种方式找试探点,通过一系列的试探点来确定极小点。另一类是函数逼近法或插值法:这类方法是用某种较简单的曲线逼近本来的函数曲线,通过求逼近函数的极小点来估计目标函数的极小点。这里采用的是第一类试探法中的黄金分割法。实现过程如下:

⑴ 置初始区间[a1,b1]及精度要求L>0,计算试探点?1和?1,计算函数值

f??1?和f??1?,计算公式是:?1?a1?0.382?b1?a1?,?1?a1?0.618?b1?a1?。令

k=1。

⑵ 若

bk?ak?Lf??k?则停止计算。否则,当f??K?>时,转步骤⑶;当

f??K??f??k?时,转步骤⑷ 。

⑶ 置数值

f??k?1?ak?1??k,

bk?1?bk,

?k?1??k,

?k?1?ak?1?0.618?bk?1?ak?1?,计算函

,转⑸。

ak?1?ak ⑷ 置函数值

f??k?1?,

bk?1??k,

?k?1??k,

?k?1?ak?1?0.382?bk?1?ak?1?,计算

,转⑸。

最速下降法

实现原理描述:在求目标函数极小值问题时,总希望从一点出发,选择一个目

标函数值下降最快的方向,以利于尽快达到极小点,正是基于这样一种愿望提出的最速下降法,并且经过一系列理论推导研究可知,负梯度方向为最速下降方向。

最速下降法的迭代公式是x?k?1??x?k???kd?k?,其中d?k?是从x?k?出发的搜索方向,这里取在点x?k?处最速下降方向,即d?k????f?xk?。?k是从x?k?出发沿方向d?k?进行的一维搜索步长,满足f?x?k???kd?k???minf?x?k???d?k??。

??0实现步骤如下:

⑴ 给定初点x?1??Rn ,允许误差??0,置k=1。

⑵ 计算搜索方向d?k????f?xk?, 若d?k???,则停止计算;否则,从x?k?出发,沿方向d?k?进行的一维搜索,求?k,使f?x?k???kd?k???minf?x?k???d?k??。

??0 ⑶ x?k?1??x?k???kd?k?,置k=k+1返回步骤 ⑵。

牛顿法

牛顿法迭代公式:x?k?1??x?k???kd?k?,d?k?是在点x?k?处的牛顿方向,

d?k????f?x2?k???1?f?x?k??,?k是从x?k?出发沿牛顿方向d?k?进行搜索的最优步长。

⑴ 给定初点x?1??Rn ,允许误差??0,置k=1。

⑵ 计算g?k???f?xk?, 若g?k???,则停止计算;否则,转⑶。 ⑶ 计算d?k????2f?x?k??gk,从x?k?出发,沿方向d?k?进行的一维搜索,

?1求?k,使f?x?k???kd?k???minf?x?k???d?k??,x?k?1??x?k???kd?k?,置k=k+1返回

??0步骤 ⑵。

共轭梯度法

若d?1?,d?2?,?,d?k?是Rn中k个方向,它们两两关于A共轭,即满足

d?i?TAd?j??0,i?j;i,j?1,?,k,称这组方向为A的k个共轭方向。共轭梯度法的

基本思想是把共轭性与最速下降法相结合,利用已知点处的梯度构造一组共轭方

向,并沿这组方向进行搜索,求出目标函数的极小点,根据共轭方向的基本性质这种方法具有二次终止性。

实现步骤如下:

⑴ 给定初点x?1??Rn ,允许误差??0; ⑵ 若?f(x1)??,则停止计算;否则,转⑶; ⑶ 置d?1????f?x?1??,k=1。

⑷ 作一维搜索,求?k,满足f?x?k???kd?k???minf?x?k???d?k??;

??0⑸ 令x?k?1??x?k???kd?k?,求g?k?1???f?x?k?1??。 ⑹ 若g?k?1???,则停止计算;否则,转⑺; ⑺ 若k=n,则令x?1??x?n?1?,转⑶;否则,转8);

gx⑻ 令d?k?1???g(k?1)??kd?k?,其中?k???k?1??k??22gx??,置k=k+1,转⑷。

程序

#include #include #include

#define N 100

double F(double x[],double p[],double xi[],double ba[],int n,double t) { }

double f=0; int i;

for(i=0;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

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

} i=0;

while(sqrt(sum)>eps&&i

sum=0;

arph=HJFC(x,p,xi,ba,n); for(i=0;i

sum=sum+p[i]*p[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\

printf(\步长lambda=%f\\n\ for(i=0;i

printf(\

printf(\ k++;

}

printf(\最后结果为:\\n\

for(i=0;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

g[i]=2*xi[i]*(x[i]-ba[i]); sum1+=g[i]*g[i];

}

while((sqrt(sum1)>eps)&&(k

if(k==1) {

for(i=0;i

bita=0; } else

{

bita=sum1/sum2; for(i=0;i

p[i]=-g[i]+bita*p[i];

}

arph=HJFC(x,p,xi,ba,n); sum1=0;

sum2=0;

for(i=0;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\ printf(\步长lambda=%f\\t\ printf(\ for(i=0;i

}

printf(\最后结果为:\\n\ for(i=0;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

printf(\过程\\n\\n\

while((sqrt(sum)>eps)&&(k

for(j=0;j

if(i==j)

h[i][j]=-1/(2*xi[i]);

printf(\

else

h[i][j]=0;

for(i=0;i

for(j=0;j

p[i]=p[i]+h[i][j]*g[j]; arph=HJFC(x,p,xi,ba,n); sum=0;

for(i=0;i

{

g[i]=2*xi[i]*(x[i]-ba[i]); sum+=g[i]*g[i];

x[i]=x[i]+arph*p[i];

}

printf(\第%d次迭代:\\n\\n\ printf(\步长lambda=%f\\n\ for(i=0;i

}

printf(\最后结果为:\\n\ for(i=0;i

void main() { int i,n; double x[N],xi[N],ba[N]; printf(\请输入函数的元数:\ scanf(\

printf(\请输入函数的系数:\ for(i=0;i

scanf(\ printf(\请输入ba[i]的值:\ for(i=0;i

scanf(\ printf(\请输入初始值:\\n\ for(i=0;i

scanf(\

/* printf(\最速下降法迭代过程:\\n\ zuisu(x,xi,ba,n);*/

/* printf(\牛顿法迭代过程:\\n\ niudun(x,xi,ba,n);*/

printf(\共轭梯度法迭代过程:\\n\ }

gonge(x,xi,ba,n);

printf(\

本文来源:https://www.bwwdw.com/article/pu8p.html

Top