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

📄 sumt_method.cpp

📁 惩罚函数中的外点约束方法
💻 CPP
字号:
//外点惩罚函数法 
//问题: minf(x)=x1*x4*(x1+x2+x3)+x3
//      s.t.  g1(x)=x1^2+x2^2+x3^2+x4^2-40=0
//            g2(x)=25-x1*x2*x3*x4
//            1<=xj<=5   j=1,2,3,4

//n-设计变量的维数;
//nc-约束条件的个数;
//ne-等式约束条件的个数;
//tt-一维搜索的初始步长;
//ff-差分法求梯度时的步长;
//ac-外点惩罚函数法和变尺度法的收敛精度;
//ad-一维搜索时的收敛精度;
//bw-惩罚因子递增系数;
//r-初始惩罚因子;
//xk[n]-设计变量的初始点。
  
//#include"stdio.h"
#include "iostream"
#include"stdlib.h"
#include"math.h"
using namespace std;

#define n 2
#define nc 5
#define tt 0.005
#define ff 0.00001
#define ac 0.000001
#define ad 0.0000001
#define bw 0.5
double r,ia;
double fun(double *x,double *c);
double *iterate(double *x,double a,double *s);
double construct(double *x);
double penalty(double *x,double a,double *s);
void finding(double a[3],double f[3],double *xk,double *s);
double lagrange(double *xk,double *ft,double *s);
double *gradient(double *xk);
double *bfgs(double *xk);
void main()
{//int j;
   int sum=0;
   double c[nc];
   double *xk1,f1,f2,q;
   double xk[n]={5,5};      
  xk1=(double *)malloc(n*sizeof(double)); 
  r=37.5;
//cout<<"请输入初始点:";
//for(int i=0;i<n;i++)
   //cin>>xk[i];        // 输入初始点
//for( i=0;i<n;i++)
    //cout<<xk[i]<<"\t";
   f1=fun(xk,c);
for(int k=0;;k++)
 {
    ia=0;
    xk1=bfgs(xk);
	//for(j=0;j<n;j++)
	//printf("\nxk1[%d]=%f",j,xk1[j]);
	f2=fun(xk1,c);
    //printf("\nf2=%f\n",f2);   
    double xx=0; 
  if(nc!=0)
  { q=fabs(c[0]);
      for(int i=0;i<nc;i++)
           if(fabs(c[i])<q)
                q=fabs(c[i]); 
  }
    if(q<=ac) break;
    for(int i=0;i<n;i++)
             xx+=pow((xk1[i]-xk[i]),2);
    xx=sqrt(xx); 
    if((fabs(xx)<=ac)&&(fabs(f2-f1)<=ac)) break;
  r=bw*r;
    for(int i=0;i<n;i++)
            xk[i]=xk1[i];
            f1=f2;
	sum++;
 }
   if(f2>f1)
   {  f2=f1;  xk1=xk;}
   cout<<"\n\t循环次数:sum="<<sum<<"\n";
   cout<<"\n\t惩罚因子:"<<"r="<<r<<"\n";
   for(int k=0;k<n;k++)
        cout<<"\n\t"<<"x*["<<k<<"]="<<xk1[k];
  //free(xk1);
   cout<<"\n\t"<<"f="<<f2<<"\n";
   for(int k=0;k<nc;k++)
      cout<<"\n\t"<<"c["<<k<<"]="<<c[k];
   cout<<"\n";
}

double fun(double *x,double *c)  
{ 
   double f;
   f=60-10*x[0]-4*x[1]+pow(x[0],2)+pow(x[1],2)-x[0]*x[1];

   c[0]=-x[0];
   c[1]=-x[1];
   c[2]=x[0]-6;
   c[3]=x[1]-8;
   c[4]=x[0]+x[1]-11;
   /*f=pow((x[1]),3)*((x[0]-3)*(x[0]-3)-9)/27/sqrt(3);
 c[0]=x[1]-x[0]/sqrt(3);
 c[1]=-x[0]+x[1]/sqrt(3);
 c[2]=x[0]+x[1]/sqrt(3)-6;
 c[3]=-x[0];
 c[4]=-x[1];*/
   return(f);
 }
double *iterate(double *x,double a,double *s)
 {
      double *x1;
      x1=(double *)malloc(n*sizeof(double));
      for(int i=0;i<n;i++)
           x1[i]=x[i]+a*s[i];
      return(x1);
 }

double construct(double *x)
   {
     double y,c[nc];
     y=fun(x,c);
     if(nc==0)   return(y);
     for(int i=0;i<nc;i++)
		 y-=r/c[i];
     return(y);
     }
 
 double penalty(double *x,double a,double *s) 
  {
         double y;
         double *x1;
         x1=iterate(x,a,s);
         y=construct(x1);
         return(y);
  }
 void finding(double a[3],double f[3],double *xk,double *s)
  {
     double t=tt;
     double a1,f1;
     a[0]=0;
     f[0]=penalty(xk,a[0],s);
     for(int i=0;;i++)
       {
         a[1]=a[0]+t;     f[1]=penalty(xk,a[1],s);
         if(f[1]<f[0]) break;
         if(fabs(f[1]-f[0])>=ad)
              {   t=-t;  a[0]=a[1];  f[0]=f[1];}
         else {   if(ia==1) return;
                  t=t/2;    ia=1;     
		      }
 }
 for(int i=0;;i++)
 {     a[2]=a[1]+t;    f[2]=penalty(xk,a[2],s);
       if(f[2]>f[1])  break;
       t=2*t;
       a[0]=a[1];    f[0]=f[1];
       a[1]=a[2];    f[1]=f[2];
 }
 if(a[0]>a[2])
 {   a1=a[0];    f1=f[0];
     a[0]=a[2];    f[0]=f[2];
     a[2]=a1;      f[2]=f1;  
   } //调试中问题所在 大括弧
 return;
 }
 
double lagrange(double *xk,double *ft,double *s)
   {
     double a[3],f[3];
     double b,c,d,aa;
     finding(a,f,xk,s);
     for(int i=0;;i++)
      {
       if(ia==1) { aa=a[1];  *ft=f[1];  break;  }
     d=(pow(a[0],2)-pow(a[2],2))*(a[0]-a[1])-(pow(a[0],2)-pow(a[1],2))*(a[0]-a[2]);
     if(fabs(d)==0)   break;
     c=((f[0]-f[2])*(a[0]-a[1])-(f[0]-f[1])*(a[0]-a[2]))/d;
     if(fabs(c)==0)   break; 
     b=((f[0]-f[1])-c*(pow(a[0],2)-pow(a[1],2)))/(a[0]-a[1]);
     aa=-b/(2*c);
     *ft=penalty(xk,aa,s);
     if(fabs(aa-a[1])<=ad)
        { if(*ft>f[1])  aa=a[1];
          break;   
	    }
     if(aa>a[1])
        {
           if(*ft>f[1])    {  a[2]=aa;  f[2]=*ft;  }
           else if(*ft<f[1])   
                 {  a[0]=a[1];a[1]=aa;   
		            f[0]=f[1];   f[1]=*ft;  
		         }
           else if(*ft=f[1])
                 {  a[2]=aa;   a[0]=a[1]; 
                    f[2]=*ft;  f[0]=f[1];       
                    a[1]=(a[0]+a[2])/2;  
					f[1]=penalty(xk,a[1],s);  
		         }
           }
      else
         {  if(*ft>f[1])     {    a[0]=aa;    f[0]=*ft;   }
            else if(*ft<f[1])
                  {    a[2]=a[1];     a[1]=aa;
                       f[2]=f[1];     f[1]=*ft;
                      }
           else if(*ft=f[1])
                {     a[0]=aa;    a[2]=a[1];
                      f[0]=*ft;    f[2]=f[1];
                      a[1]=(a[0]+a[2])/2;    f[1]=penalty(xk,a[1],s);
                        }
                }
            }
     if(*ft>f[1])
         {   aa=a[1];     *ft=f[1];     }
     return(aa);
   }
 double *gradient(double *xk)
 {
    double *g,f1,f2,q;
    g=(double *)malloc(n*sizeof(double));
    f1=construct(xk);
    for(int i=0;i<n;i++)
       {  q=ff;
          xk[i]=xk[i]+q;      f2=construct(xk);
          g[i]=(f2-f1)/q;  xk[i]=xk[i]-q;
       }
     return(g);
 }
double *bfgs(double *xk)
  {
    double u[n],v[n],h[n][n],dx[n],dg[n],s[n];
    double aa,ib=0;
    double *ft,*xk1,*g1,*g2,*xx,*x0=xk;
    ft=(double *)malloc(sizeof(double));
    xk1=(double *)malloc(n*sizeof(double)); 
    int i,j,k;
    
    for(i=0;i<n;i++)
      { s[i]=0;
        for(j=0;j<n;j++)
       {  h[i][j]=0;
          if(j==i)  
          h[i][j]=1; 
		}
      }
    g1=gradient(xk);
   //for(j=0;j<n;j++)
	//printf("\ng1[%d]=%f\n",j,g1[j]);
    double fi=construct(xk);
    //printf("fi=%f",fi);
    x0=xk;
  for(k=0;k<n;k++)
    { int ib;
      if(ia==1 )  {  xx=xk; break; }
      ib=0; 
      for(i=0;i<n;i++)
        s[i]=0;
      for(i=0;i<n;i++)
        for(j=0;j<n;j++)
         s[i]+=-h[i][j]*g1[j];
     aa=lagrange(xk,ft,s);
    //printf("aa=%f ",aa);
     xk1=iterate(xk,aa,s);
     g2=gradient(xk1);
     for(i=0;i<n;i++)
       if((fabs(g2[i])>=ac)&&(fabs(g2[i]-g1[i])>=ac)||(fabs(*ft-fi)>=ac))
           ib=ib+1;
       if(ib==0)
         {  xx=xk1;  break;   }
       fi=*ft;
       if(k==(n-1))
        { xk=xk1;
        for(i=0;i<n;i++)
        for(int j=0;j<n;j++)
         {  h[i][j]=0;
           if(j==i) h[i][j]=1;
       }
        g1=g2;
        k=-1;
      }
       else  
     {
       for(i=0;i<n;i++)
	   { dg[i]=g2[i]-g1[i];
         dx[i]=xk1[i]-xk[i];    }
         for(i=0;i<n;i++)
        {
       u[i]=0;    v[i]=0;
       for(int j=0;j<n;j++)
      {  u[i]=u[i]+dg[j]*h[i][j];  
         v[i]=v[i]+dg[j]*h[i][j]; 
      }
      }
   double a1=0,a2=0;
   for(int j=0;j<n;j++)
    { a1+=dx[j]*dg[j];    
      a2+=v[j]*dg[j];    
    }
   if(fabs(a1)!=0)
    {a2=1+a2/a1;
   for(i=0;i<n;i++)
   for(int j=0;j<n;j++)
    h[i][j]+=(a2*dx[i]*dx[j]-v[i]*dx[j]-dx[i]*u[j])/a1;
   }
   xk=xk1;g1=g2;
	   }
 }
 if(*ft>fi)
  {   *ft=fi;   xx=xk;    }
      xk=x0;
	  return(xx);
   }

⌨️ 快捷键说明

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