机械优化设计——复合形方法及源程序
(一) 题目:用复合形法求约束优化问题
()()()2
22
1645min -+-=x x x f ;0642
22
11≤--=x x g ;01013≤-=x g 的最优解。
基本思路:在可行域中构造一个具有K 个顶点的初始复合形。对该复合形各顶点的目标函数值进行比较,找到目标函数值最大的顶点(即最坏点),然后按一定的法则求出目标函数值有所下降的可行的新点,并用此点代替最坏点,构成新的复合形,复合形的形状每改变一次,就向最优点移动一步,直至逼近最优点。
(二) 复合形法的计算步骤
1)选择复合形的顶点数k ,一般取n k n 21≤≤+,在可行域内构成具有k 个顶点的初始
复合形。
2)计算复合形个顶点的目标函数值,比较其大小,找出最好点x L 、最坏点x H 、及此坏点
x G..
3)计算除去最坏点x H 以外的(k-1)个顶点的中心x C 。判别x C 是否可行,若x C 为可行点,
则转步骤4);若x C 为非可行点,则重新确定设计变量的下限和上限值,即令
C L x b x a ==,,然后转步骤1),重新构造初始复合形。
4)按式()H C C R x x x x -+=α计算反射点x R,必要时改变反射系数α的值,直至反射成
功,即满足式()()()()H R R j x f x f m j x g ?=≤;,2,1,0,。然后x R以取代x H,构成新的复合形。
5)若收敛条件()()[]
ε≤??
?
?????--∑=2
1
1211k j L j x f x f k 得到满足,计算终止。约束最优解为:()()L L x f x f x x ==*,*。
(三) 复合形法程序框图见下图:
{
scanf("%d",&n);
printf("请输入复合形的顶点数k:");
scanf("%d",&k);
double **x=apply(k,n); /*存放复合形顶点*/
double *y=(double *)calloc(k,sizeof(double)); /*存放目标函数值*/ double *p=(double *)calloc(3,sizeof(double)); /*存放约束函数值*/ double *a=(double *)calloc(n,sizeof(double)); /*存放设计变量的下限*/
double *b=(double *)calloc(n,sizeof(double)); /*存放设计变量的上限*/
double *x_c=(double *)calloc(n,sizeof(double)); /*存放可行点中心*/ double *x_r=(double *)calloc(n,sizeof(double)); /*存放最坏点的反射点*/
printf("本程序中的所有输入,两个数之间用空格隔开,然后按enter键时不要长时间的按,否则,可能会出错\n");
printf("请输入选定的第一个可行点x1(包含%d个数):",n);
for(i=0;i scanf("%lf",*x+i); printf("请输入初选变量的下限a(包含%d个数):",n); for(i=0;i scanf("%lf",a+i); printf("请输入初选变量的上限b(包含%d个数):",n); for(i=0;i scanf("%lf",b+i); printf("输出输入结果为:\nn=%d,k=%d,x1=(",n,k); /*输出已知数据*/ for(i=0;i printf("%.5lf ",*(*x+i)); printf("%.5lf)\na=(",*(*x+n-1)); for(i=0;i printf("%f ",*(a+i)); printf("%.5lf),b=(",*(a+n-1)); for(i=0;i printf("%f ",*(b+i)); printf("%.5lf)\n",*(b+n-1)); L1: for(i=1;i for(j=0;j *(*(x+i)+j)=*(a+j)+(double)(rand()%10000)/10000*(*(b+j)-*(a+j)); l=1; for(i=1;i if(judge(*(x+i))) { for(j=1;j if(!judge(*(x+j))) { for(k1=0;k1 { temporary=*(*(x+i)+k1); *(*(x+i)+k1)=*(*(x+j)+k1); *(*(x+j)+k1)=temporary; } break; } l++; } for(i=0;i if(f(*(x+i)) for(k1=0;k1 { temporary=*(*(x+i)+k1); *(*(x+i)+k1)=*(*(x+j)+k1); *(*(x+j)+k1)=temporary; } for(i=0;i *(x_c+i)=0; for(i=0;i for(j=0;j *(x_c+j)+=*(*(x+i)+j); for(i=0;i *(x_c+i)/=l; if(!judge(x_c)) /*判断可行点中心是否可行*/ { for(i=0;i { *(a+i)=*(*(x+l-1)+i); *(b+i)=*(x_c+i); } goto L1; } else { for(i=l;i do{ for(j=0;j *(*(x+i)+j)=*(x_c+j)+*(*(*(x+i)+j)-*(x_c+j)); }while(!judge(*(x+i))); L2: for(i=0;i if(f(*(x+i)) for(k1=0;k1 { temporary=*(*(x+i)+k1); *(*(x+i)+k1)=*(*(x+j)+k1); *(*(x+j)+k1)=temporary; } restrain=0; /*求收敛条件*/ for(i=0;i restrain+=(f(*(x+i))-f(*(x+k-1)))*(f(*(x+i))-f(*(x+k-1))); restrain=sqrt(k-1)*restrain); if(restrain { printf("\n求得约束最优点为:( "); for(i=0;i printf("%.5f ",*(*(x+k-1)+i)); printf(")\n目标函数的最优解为:%.5f\n",f(*(x+k-1))); return 0; } else { L3: for(i=0;i *(x_c+i)=0; for(i=1;i for(j=0;j *(x_c+j)+=*(*(x+i)+j); for(i=0;i *(x_c+i)/=k-1; reflect=; L4: for(i=0;i *(x_r+i)=*(x_c+i)+reflect*(*(x_c+i)-*(*x+i)); if(!judge(x_r)) { reflect*=; goto L4; } else if(f(x_r) { for(i=0;i *(*x+i)=*(x_r+i); goto L2; } else if(reflect<=1e-10) { for(i=0;i *(*x+i)=*(*(x+1)+i); goto L3; } else { reflect*=; goto L4; } } } } double **apply(int row,int col) /*申请矩阵空间*/ { int i; double *x=(double*)calloc(row*col,sizeof(double)); double **y=(double **)calloc(row,sizeof(double *)); if(!x || !y) { printf("内存分配失败!"); exit(1); } for(i=0;i *(y+i)=x+i*col; return y; } double f(double *x) /*目标函数*/ { return (*x-5)*(*x-5)+4*(*(x+1)-6)*(*(x+1)-6); } double *g(double *x) /*约束函数*/ { double *p=(double *)calloc(3,sizeof(double)); if(!p) { printf("内存分配失败!"); exit(1); } *p=64-(*x)*(*x)-(*(x+1))*(*(x+1)); *(p+1)=*(x+1)-*x-10; *(p+2)=*x-10; return p; } bool judge(double *x) /*可行点的判断*/ { int i; double *p=(double *)calloc(3,sizeof(double)); p=g(x); for(i=0;i<3;i++) if(*(p+i)>0) break; if(i==3) return true; else return false; } (五)运行结果如下: