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 + -
显示快捷键?