dcx.cpp

来自「优化设计中使用的单纯形法的类。 稍改进」· C++ 代码 · 共 271 行

CPP
271
字号
#include <iostream.h>
#include <math.h>

double fxy1(double *p)   //目标函数外部给出,变量用指针表示:*(p+i),i=0,1,2……
{
	return(4*(*p-5)*(*p-5)+(*(p+1)-6)*(*(p+1)-6)+((*(p+2)-10)*(*(p+2)-10)));
}

double fxy2(double *p)
{
	return(10*(*p+*(p+1)-5)*(*p+*(p+1)-5)+(*p-*(p+1))*(*p-*(p+1)));
}

double fxy3(double *p)
{
	return(*p**p+4**(p+1)**(p+1));
}
double fxy4(double *p)
{
	return(*p**p+*(p+1)**(p+1)-*p**(p+1)-10**p-4**(p+1)+60);
}

double fxy(double *p)
{
	return(4*(*p)*(*p)+(*(p+1)-1)*(*(p+1)-1)+1.0/(*p+*(p+1)-6));
}

class dcx
{
private:
	double xl,xh,xg,xc;
	int n,f_xl,f_xh,f_xg,k;
public:
	void paixu(double *m)
	{
		int i;
		xl = *m;
		xh = *m;
		xg = *m;
		f_xl = 0;
		f_xh = 0;
		f_xg = 0;
		for(i=0;i<n+1;i++)
		{
			if(*(m+i)<xl)
			{
				xl = *(m+i);
				f_xl = i;
			}
			if(*(m+i)>xh)
			{
				xh = *(m+i);
				f_xh = i;
			}
		}
		xg = xl;
		f_xg = f_xl;
		for(i=0;i<n+1;i++)
		{
			if(xg<*(m+i)&&i!=f_xh)
			{
				xg = *(m+i);
				f_xg = i;
			}
		}
	}

	void xingxin(double *mm,double *cc) 
	{
		int i,j;
		for(i=0;i<n;i++)
			*(cc+i) = 0;
		for(i=0;i<n;i++)
		{
			for(j=0;j<n+1;j++)
				if(j!=f_xh)
					*(cc+i) += *(mm+i*(n+1)+j);
		}
		for(i=0;i<n;i++)
			*(cc+i) = *(cc+i)/n;
		xc = fxy(cc);
	}

	void action(int nn,double jing)
	{
		int i,j;
		double h = 1.6;
		double ass;
		n = nn+1;
		k=0;
		double *p = new double [n*(n+1)];   //所有分量值
		double *e = new double [n*n];   //单位分量

		
  
     //  double temp[6];
	  // double temp2[3];

	   

		
		for(i=0;i<(n*n);i++)
		{
			if(i/n==i%n)
				*(e+i) = 1.0;
			else
				*(e+i) = 0.0;
		}

		

		for(i=0;i<n*(n+1);i+=n+1)   //设置初值为0
			*(p+i) = 100.0;

		
		for(i=0;i<n*(n+1);i++)
			if(i%(n+1)!=0)
				*(p+i) = *(p+i-i%(n+1))+h**(e+i-1-i/(n+1));
		delete e;

		
		
     ass = 2*(n+1)*jing*jing;  //保证进入循环

	 xl = ass;
	 

        double *w = new double [n];   //暂存点的坐标分量
		double *g = new double [n+1];  //各个点对应的函数值


     while(k++,sqrt(1.0/(n+1)*ass)>jing)   //sqrt(1.0/(n+1)*ass)
	 {

		

		for(j=0;j<n+1;j++)       //求每个点的函数值放入 g
		{
			for(i=0;i<n;i++)
				*(w+i) = *(p+i*(n+1)+j);
			*(g+j) = fxy(w);
		}

     /*  for(i=0;i<3;i++)
	         temp2[i] = *(g+i);*/



		paixu(g);    //对各个点进行排序,记录最优,最差,次差点。

		double *c = new double [n];  //形心点
		xingxin(p,c);
		xc = fxy(c);

		

		double *r = new double [n];  //反射点

		for(i=0;i<n;i++)
		{
			*(r+i) = *(c+i)+1.0*(*(c+i)-*(p+i*(n+1)+f_xh));
		}

        if(fxy(r)<xl)
		{
			double *ee = new double [n];  //扩张点
			for(i=0;i<n;i++)
			{
				*(ee+i) = *(c+i) + 2.0*(*(r+i)-*(c+i));
			}

			if(fxy(ee)<xl)
				for(i=0;i<n;i++)
					*(p+i*(n+1)+f_xh) = *(ee+i);
			else
				for(i=0;i<n;i++)
					*(p+i*(n+1)+f_xh) = *(r+i);
			delete ee;
			delete r;
			delete c;
		}
		else if(fxy(r)<xg)
		{
            for(i=0;i<n;i++)
					*(p+i*(n+1)+f_xh) = *(r+i);
			delete r;
			delete c;
		}
		else
		{
			if(fxy(r)<xh)
			{
			
			for(i=0;i<n;i++)
				*(p+i*(n+1)+f_xh) = *(c+i);
			}
		    
			
			double *s = new double[n];   //压缩点
			for(i=0;i<n;i++)
				*(s+i) = *(c+i)+0.5*(*(p+i*(n+1)+f_xh)-*(c+i));
			
			if(fxy(s)>xh)
			{
				for(i=0;i<n*(n+1);i++)
				{
					*(p+i) = *(p+(i/(n+1))+f_xl)+0.5*(*(p+i)-*(p+(i/(n+1))+f_xl));
				}
				delete s;

			}
			else
			{
                for(i=0;i<n;i++) 
				*(p+i*(n+1)+f_xh) = *(s+i);
				delete s;
			}
			delete r;
			delete c;
		}

      /* for(i=0;i<6;i++)
		   temp[i] = *(p+i);*/


         ass = 0;
		 for(j=0;j<n+1;j++)       //求每个点的函数值放入 g
		{
			for(i=0;i<n;i++)
				*(w+i) = *(p+i*(n+1)+j);
			*(g+j) = fxy(w);
		}
		for(i=0;i<n+1;i++)
		{
	       ass+=(*(g+i)-xc)*(*(g+i)-xc);
		}

  /*for(i=0;i<3;i++)
	  temp2[i] = *(g+i);*/

        
	

		
	 }

	 
    delete g;
	delete w;

     //cout<<endl;
	 //cout<<f_xl<<"   "<<f_xh<<"    "<<f_xg;
	 //cout<<endl;cout<<endl;
	 for(i=0;i<n-1;i++)
		 cout<<"X"<<i+1<<" = "<<*(p+i*(n+1)+f_xl)<<'\t'<<endl;
	 cout<<"迭代次数为"<<k<<endl;

	 delete p;
	 

	}

};

void main()
{
	dcx eg;
	eg.action(3,0.000000001);  //当维数增加一的时候,结果更精确,为什么?
}

⌨️ 快捷键说明

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