一维寻优问题各位ggjjddmm
最优化-无约束共轭梯度法程序(c++)
/////////////////////////////////////////
/////vector。h头文件/////
/////定义向量及其基本运算/////
/////////////////////////////////////////
#i nclude
#defineMAXLENGTH10
//向量定义
typedefstruct{
inttag;//行列向量标志。 行向量为0,列向量为1。
intdimension;//向量的维数
doubleelem[MAXLENGTH];//向量的元素
}vector;
vectorvec...全部
最优化-无约束共轭梯度法程序(c++)
/////////////////////////////////////////
/////vector。h头文件/////
/////定义向量及其基本运算/////
/////////////////////////////////////////
#i nclude
#defineMAXLENGTH10
//向量定义
typedefstruct{
inttag;//行列向量标志。
行向量为0,列向量为1。
intdimension;//向量的维数
doubleelem[MAXLENGTH];//向量的元素
}vector;
vectorvecCreat(inttag,intn){
//建立维数为n的向量
vectorx;
x。
tag=tag;
x。dimension=n;
for(inti=0;i
#i nclude"vector。h"
#defineSIZE10
#defineMAX1e300
doublemin(doublea,doubleb){
//求两个数最小
returna}
doublemax(doublea,doubleb){
//求两个数最大
returna>b?a:b;
}
vectorvecGrad(double(*pf)(vectorx),vectorpointx){
//求解向量的梯度
//采用理查德外推算法计算函数pf在pointx点的梯度grad;
vectorgrad;
grad。
tag=1;grad。dimension=pointx。dimension;//初始化偏导向量
vectortempPnt1,tempPnt2;//临时向量
doubleh=1e-3;
for(inti=0;itempPnt1=tempPnt2=pointx;
tempPnt1。
elem[i]+=0。5*h;
tempPnt2。elem[i]-=0。5*h;
grad。elem[i]=(4*(pf(tempPnt1)-pf(tempPnt2)))/(3*h);
tempPnt1。
elem[i]+=0。5*h;
tempPnt2。elem[i]-=0。5*h;
grad。elem[i]-=(pf(tempPnt1)-pf(tempPnt2))/(6*h);
}
returngrad;
}
doublevecFun(vectorvx){
//最优目标多元函数
doublex[SIZE];
for(inti=0;ix[i+1]=vx。
elem[i];
//----------约束目标函数--------------
//returnx[1]*x[1]+x[2]*x[2];
//----------无约束正定函数--------------
//returnx[1]*x[1]+4*x[2]*x[2]+9*x[3]*x[3]-2*x[1]+18*x[3];//例一
//----------无约束非二次函数--------------
//return(1-x[1])*(1-x[1])+(1-x[4])*(1-x[4])+(x[1]*x[1]-x[2])*(x[1]*x[1]-x
[2])+(x[2]*x[2]-x[3])*(x[2]*x[2]-x[3])+(x[3]*x[3]-x[4])*(x[3]*x[3]-x[4]);//例二
}
doublevecFun_Si(vectorvx){
//不等式约束函数
doublex[SIZE];
for(inti=0;ix[i+1]=vx。
elem[i];
returnx[1]+1;//不等式约束函数
}
doublevecFun_Hi(vectorvx){
//等式约束函数
doublex[SIZE];
for(inti=0;ix[i+1]=vx。
elem[i];
returnx[1]+x[2]-2;//等式约束函数
}
doublevecFun_S(vectorx,doublev,doublel,doubleu){
//约束问题转化为无约束问题的增广目标函数F(x,v,l,u)
doublesum1=0,sum2=0,sum3=0;//分别定义三项的和
//sum1
doubletemp=max(0,v-2*u*vecFun_Si(x));
sum1=(temp*temp-v*v)/(4*u);
//sum2
sum2=l*vecFun_Hi(x);
//sum3
sum3=u*vecFun_Hi(x)*vecFun_Hi(x);
//F(x,v,l,u)=f(x)+sum1-sum2+sum3
returnvecFun(x)+sum1-sum2+sum3;
}
vectorvecFunD_S(vectorx,doublev,doublel,doubleu){//利用重载函数实现目标函
数F(x,v,l,u)的导数
//约束问题转化为无约束问题的增广目标函数F(x,v,l,u)的导函数
vectorsum1,sum2,sum3;//分别定义三项导数的和
//sum1
sum1。
dimension=x。dimension;sum1。tag=1;
sum2。dimension=x。dimension;sum2。tag=1;
sum3。dimension=x。dimension;sum3。
tag=1;
doubletemp=max(0,v-2*u*vecFun_Si(x));
if(temp==0){
for(inti=0;isum1。elem[i]=0;
}
else{
sum1=numMultiply(-(v-2*u*vecFun_Si(x)),vecGrad(vecFun_Si,x));
}
//-sum2
sum2=numMultiply(-l,vecGrad(vecFun_Hi,x));
//sum3
sum3=numMultiply(2*u*vecFun_Hi(x),vecGrad(vecFun_Hi,x));
//F=f(x)+sum1-sum2+sum3
returnvecAdd(vecAdd(vecGrad(vecFun,x),sum1),vecAdd(sum2,sum3));
}
///////////////////////////////////////////////////
/////nonrestrict。
h头文件/////
/////包含无约束问题的求解函数:直线搜索/////
/////共轭梯度法,H终止准则/////
///////////////////////////////////////////////////
#i nclude"restrict。
h"
vectorlineSearch(vectorx,vectorp,doublet){
//从点x沿直线p方向对目标函数f(x)作直线搜索得到极小点x2,t为初始步长。
vectorx2;
doublel=0。
1,n=0。4;//条件1和2的参数
doublea=0,b=MAX;//区间
doublef1=0,f2=0,g1=0,g2=0;
inti=0;//迭代次数
do{
if(f2-f1>l*t*g1){b=t;t=(a+b)/2;}//改变b,t循环
do{
if(g2f1=vecFun(x);//f1=f(x)
g1=vecMultiply(vecConvert(vecGrad(vecFun,x)),p);//g1=∨f(x)*p
x2=vecAdd(numMultiply(t,p),x);//x2=x+t*p
if(i++&&vecFun(x2)==f2){returnx2;}//【直线搜索进入无
限跌代,则此次跌代结束。
返回当前最优点】
f2=vecFun(x2);//f2=f(x2)
g2=vecMultiply(vecConvert(vecGrad(vecFun,x2)),p);//g2=∨f(x2
)*p
//coutl*t*g1);//不满足条件i,则改变b,t循环
returnx2;
}
intHimmulblau(vectorx0,vectorx1,doublef0,doublef1){
//H终止准则。
给定Xk,Xk+1,Fk,Fk+1,判断Xk+1是否是极小点。返回1是极小,否则返回0
doublec1,c2,c3;//定义并初始化终止限
c1=c2=10e-5;
c3=10e-4;
if(vecMole(vecGrad(vecFun,x1))if(vecMole(vecAdd(x1,numMultiply(-1,x0)))/(vecMole(x0)+1)if(fabs(f1-f0)/(fabs(f0)+1)return1;
return0;
}
voidFletcher_Reeves(vectorxx,vector&minx,double&minf){
//Fletcher-Reeves共轭梯度法。
//给定初始点xx。对vecFun函数求得最优点x和最优解f,分别用minx和minf返回
intk=0,j=0;//迭代次数,j为总迭代次数
doublec=10e-1;//终止限c
intn=xx。
dimension;//问题的维数
doublef0,f,a;//函数值f(x),a为使p方向向量共轭的系数
vectorg0,g;//梯度g0,g
vectorp0,p;//搜索方向P0,p
vectorx,x0;//最优点和初始点
doublet=1;//直线搜索的初始步长=1
x=xx;//x0
f=vecFun(x);//f0=f(x0)
g=vecGrad(vecFun,x);//g0
p0=numMultiply(-1,g);//p0=-g0,初始搜索方向为负梯度方向
do{
x0=x;f0=f;g0=g;
x=lineSearch(x0,p0,t);//从点x出发,沿p方向作直线搜索
f=vecFun(x);//f=f(x)
g=vecGrad(vecFun,x);//g=g(x)
if(Himmulblau(x0,x,f0,f)==1){//满足H终止准则,返回最优点及最优解。
cout及其?(Y/N)";
cin>>key;
if(key=='N'||key=='n')return;
elseif(key=='Y'||key=='y'){
vectorx0;//起始点
intm;
cout>m;
x0=vecCreat(1,m);
vectorminx;//求得的极小点
doubleminf;//求得的极小值
Fletcher_Reeves(x0,minx,minf);
cout和?(Y/N)";
cin>>key;
if(key=='N'||key=='n')return;
elseif(key=='Y'||key=='y'){
vectorx0;//起始点
intm;
cout>m;
x0=vecCreat(1,m);
vectorminx;//求得的极小点
doubleminf;//求得的极小值
Hesternes(x0,minx,minf);
showPoint(minx,minf);
}
}
voidmain(){
intmark=1;
while(mark){
printSelect();
intsel;
cin>>sel;
switch(sel){
case1:
sub1();
break;
case2:
sub2();
break;
case3:
mark=0;
break;
};
}
。
收起