⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jixie.cpp

📁 约束优化方法—惩罚函数法的c++源程序
💻 CPP
字号:
#include<iostream.h>
#include<math.h>
double lamta[10]={0, 1.0 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,1};//鲍威尔方法初始化方向,线性无关
double lamta1[3]={0, 0 , 0};//暂存新的搜索方向
double x1[4]={0, 0 ,0, 0 };//x1到x3用于存储各共轭方向的点
double x2[4]={0, 0 ,0, 0 };
double x3[4]={0, 0 ,0, 0 };
double x4[4]={0, 0 ,0, 0 };//x4用于中间判断
double x5[4]={0, 0 ,0, 0 };//x5用存放于更换方向后产生的新点
int m=0;//标志
double x_[4]={0, 0, 0, 0};//暂存鲍威尔最优解
double x0[4]={0, 2, 2 , 2};//初值 
double c=10;//递减系数
double e=0.00001;//精度控制
double r0=1;//初始惩罚因子
double r=1;
//函数声明部分
void Powell(double r);   //鲍威尔方法函数
double fxy(double x1,double x2,double x3,double r);  //待求函数
double ysearch(double x);  //一维搜索的目标函数
void search(double &a,double &b,double h);   //区间搜索
double  yellowcut(double &a,double &b);  //黄金分割
void sort(double *p,int size);//选择法排序
void main()                     //约束优化方法主函数入口
{
 cout<<"请输入精度"<<endl;
  cin>>e;
changyan:Powell(r);
 double cmpare[4];
 int flag1=0;
 for (int i=1;i<=3;i++)
 {
  cmpare[i]=x_[i]-x0[i];
  if (fabs(cmpare[i])<e)
  {flag1++;}
 }
  if (flag1==3)
  {
   cout<<"最优解为:"<<"x1="<<x_[1]<<"      "<<"x2="<<x_[2]<<"     "<<"x3="<<x_[3]<<endl;
   cout<<"最小值为"<<fxy(x_[1],x_[2],x_[3],r)<<endl;
  }
  else
  {
   for (int j=1;j<=3;j++)
   {
    x0[j]=x_[j];
   }
   r=c*r;
   goto changyan;
  }
}
//子函数定义部分
double fxy(double x1,double x2,double x3,double r)//待求函数
{
 double m,n,p;
 m=(-x1>0)?(-x1):0;
 n=(-x2>0)?(-x2):0;
 p=(-x3>0)?(-x3):0;
 return    //惩罚函数
1000-x1*x1-2*x2*x2-x3*x3-x1*x2-x1*x3+r*(m*m+n*n+p*p)+r*((x1*x1+x2*x2+x3*x3-25)*(x1*x1+x2*x2+x3*x3-25)+(8*x1+14*x2+7*x3-56)*(8*x1+14*x2+7*x3-56));
}
void Powell(double r)     //鲍威尔方法函数定义
{
  double det=0.0001;      //迭代精度
 int k;
my1: for (k=1;k<=3;k++)
  {
   m=3*k-2;
   double a=0,b=0,xo=0;
   search(a,b,1);  //完成区间搜索
   double temp;
   temp=yellowcut(a,b);//黄金分割法
   int n=3*k-2;
   for (int i=1;i<=3;i++)
   {
    switch (k)
    {
    case 1:x1[i]=x0[i]+temp*lamta[n++];break;
    case 2:x2[i]=x1[i]+temp*lamta[n++];break;
    case 3:x3[i]=x2[i]+temp*lamta[n++];break;
    default :break;
    }
   }
  }
  double cmp[4];
  int flag=0;
  for (int i=1;i<=3;i++)
  {
   cmp[i]=x3[i]-x0[i];
   if (fabs(cmp[i])<det)
   {flag++;}}
  if (flag==3)     //找到最优解
  {
   x_[1]=x3[1];
   x_[2]=x3[2];
   x_[3]=x3[3];
   
  }
  else
  {
   double fy[4];
   fy[0]=fxy(x0[1],x0[2],x0[3],r);
   fy[1]=fxy(x1[1],x1[2],x1[3],r);
   fy[2]=fxy(x2[1],x2[2],x2[3],r);
   fy[3]=fxy(x3[1],x3[2],x3[3],r); double fyy[3];
   for (int ii=0;ii<3;ii++)
   {fyy[ii]=fy[ii]-fy[ii+1];}
   sort(fyy,3);
   for (ii=1;ii<=3;ii++)
   {x4[ii]=2*x3[ii]-x0[ii];}
   double f0,f3,f4;
   f0=fy[0];
   f3=fy[3];
   f4=fxy(x4[1],x4[2],x4[3],r);
   if ((f0+f4-2*f3)/2>=fyy[2])
   {
    if (f3<f4)
    {
     for (int t=1;t<=3;t++)
     {x0[t]=x3[t];}
    }
    else
    {
     for (int t=1;t<=3;t++)
     {x0[t]=x4[t];
    }}
    goto my1;
   }
   else{
    for (int t=0;t<3;t++)
    {lamta1[t]=x3[t+1]-x0[t+1];}
    m=0;                   //switch 标志!
    double aa=0,bb=0;
    search(aa,bb,1);
    double temp1;
    temp1=yellowcut(aa,bb);
    for (int i=1;i<=3;i++)
    {x5[i]=x3[i]+temp1*lamta1[i-1];}
    for (i=1;i<=3;i++)
    {x0[i]=x5[i];}
    for (i=1;i<=6;i++)
    {lamta[i]=lamta[i+3];}
    for (i=1;i<=3;i++)
    {
     lamta[6+i]=lamta1[i-1];}
    goto my1;
}}}

double ysearch(double x)  //一维搜索的目标函数
{
switch (m)
{
case 1: return fxy(x0[1]+x*lamta[m],x0[2]+x*lamta[m+1],x0[3]+x*lamta[m+2],r);break;
case 4: return fxy(x1[1]+x*lamta[m],x1[2]+x*lamta[m+1],x1[3]+x*lamta[m+2],r);break;
case 7: return fxy(x2[1]+x*lamta[m],x2[2]+x*lamta[m+1],x2[3]+x*lamta[m+2],r);break;
case 0: return fxy(x3[1]+x*lamta1[0],x3[2]+x*lamta1[1],x3[3]+x*lamta1[2],r);break;//更改方向后的一维搜索
default:return 0; break;
}
}
void search(double &a,double &b,double h)   //区间搜索
{double a1,a2,a3,y1,y2,y3;
h=1;
a1=a,y1=ysearch(a1);
a2=a+h,y2=ysearch(a2);
if(y2>=y1){
 h=-h,a3=a1,y3=y1;
 a1=a2,y1=y2,a2=a3,y2=y3;}
a3=a2+h,y3=ysearch(a3);
while(y3<=y2){
 h=2*h;
 a1=a2,y1=y2,a2=a3,y2=y3;
 a3=a2+h,y3=ysearch(a3);
}
if(h<0)a=a3,b=a1;
else a=a1,b=a3;}
double  yellowcut(double &a,double &b){
 double e;                                        //黄金分割法求解
 e=0.001;
 double c,fc;
 c=a+0.382*(b-a);
 fc=ysearch(c);
 double d,fd;
 double xo;
 d=a+0.618*(b-a);
 fd=ysearch(d);
label2: if (fc<=fd)
  {b=d;
  d=c;
  fd=fc;
  c=a+0.382*(b-a);
  fc=ysearch(c);}
  else
  {a=c;
  c=d;
  fc=fd;
  d=a+0.618*(b-a);
  fd=ysearch(d);}
  if ((b-a)<=e)
  {xo=(a+b)/2;}
  else
   goto label2;
  return xo;
}
void sort(double *p,int size){//选择法排序
 int i,j;
 double k;
 for(i=0;i<size-1;i++)
  for(j=i+1;j<size;j++)
   if(*(p+i)>*(p+j)){k=*(p+i);*(p+i)=*(p+j);*(p+j)=k;}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -