机械优化设计实验报告文件编码(008-TTIG-UTITD-GKBTT-PUUTI-WYTUI-8256)
《机械优化设计》
实验报告
目录
1.进退法确定初始区间
进退法基本思路:按照一定的规则试算若干个点,比较其函数值的大小,直至找到函数值按“高-低-高”变化的单峰区间。
进退法程序框图
题目:用进退法求解函数()2710
=-+的搜索区间
f x x x
源程序代码及运行结果
#include <>
#include <>
main()
{
float h,h0,y1,y2,y3,a1=0,a2,a3,fa2,fa3;
scanf("h0=%f,y1=%f",&h0,&y1);
h=h0;a2=h;y2=a2*a2-7*a2+10;
if (y2>y1)
{
h=-h;a3=a1;y3=y1;
loop:a1=a2;y1=y2;a2=a3;y2=y3;
}
a3=a2+2*h;y3=a3*a3-7*a3+10;
if (y3 { goto loop; } else printf("a1=%f,a2=%f,a3=%f,y1=%f,y2=%f,y3=%f\n",a1,a2,a3,y1,y2,y3); } 搜索区间为0 6 2.黄金分割法 黄金分割法基本思路:通过不断的缩短单峰区间的长度来搜索极小点的一种有效方法。按λ(618.0=λ) 缩小 比较)(x f 大小 确定取舍区间。 黄金分割法流程图 题目:对函数()279f x x x =-+,给定搜索区间08x ≤≤时,试用黄金分割法求极小点 源程序代码及结果: f=inline('x^2-7*x+9') a=0;b=8;eps=; a1=*(b-a);y1=f(a1); a2=a+*(b-a);y2=f(a2); while (abs(b-a)>eps) if(y1>=y2) a=a1; a1=a2; y1=y2; a2=a+*(b-a); y2=f(a2); else b=a2;a2=a1;y2=y1; a1=*(b-a); y1=f(a1); end end xxx=*(a+b) f = Inline function: f(x) = x^2-7*x+9 xxx = 3.牛顿型法 牛顿型法基本思路:在k x邻域内用一个二次函数()x φ来近似代替原目标函数,并将()x φ的极小点作为对目标函数() f x求优的下一个迭代点1k x+。经多次迭代,使之逼近目标函数() f x的极小点。 阻尼牛顿法的流程图: while itcl=a*dk; k=k+1; end f=(xk(1,1)-2)^4+(xk(1,1)-2*xk(2,1))^2; fprintf('\n ó×èá£ù·¨μü′ú %d ′oóμμ Dμ x*°Dμ f a:\n',k); disp(xk); disp(f); 结果显示:input x0:[1;1] 用阻尼牛顿法迭代 27 次后得到极小点 x*及极小值 f 为: 4.鲍威尔法 鲍威尔法基本思路:在不用导数的前提下,在迭代中逐次构造G的共轭方向。 鲍威尔法流程图: 4.3 题目:求函数f(x)= x[0]*x[0]+x[1]*x[1]-x[0]*x[1]-10*x[0]-4*x[1]+60的最优点,收敛精度ε= 源程序代码及结果: #include "" #include "" #include "" double objf(double x[]) {double ff; ff=x[0]*x[0]+x[1]*x[1]-x[0]*x[1]-10*x[0]-4*x[1]+60; return(ff); } void jtf(double x0[],double h0,double s[],int n,double a[],double b[]) {int i; double *x[3],h,f1,f2,f3; for(i=0;i<3;i++) x[i]=(double *)malloc(n*sizeof(double)); h=h0; for(i=0;i *(x[0]+i)=x0[i]; f1=objf(x[0]); for(i=0;i *(x[1]+i)=*(x[0]+i)+h*s[i]; f2=objf(x[1]); if(f2>=f1) {h=-h0; for(i=0;i *(x[2]+i)=*(x[0]+i); f3=f1; for(i=0;i {*(x[0]+i)=*(x[1]+i); *(x[1]+i)=*(x[2]+i); } f1=f2; f2=f3; } for(;;) {h=2*h; for(i=0;i *(x[2]+i)=*(x[1]+i)+h*s[i]; f3=objf(x[2]); if(f2 else { for(i=0;i {*(x[0]+i)=*(x[1]+i); *(x[1]+i)=*(x[2]+i); } f1=f2; f2=f3; } } if(h<0) for(i=0;i {a[i]=*(x[2]+i); b[i]=*(x[0]+i); } else for(i=0;i {a[i]=*(x[0]+i); b[i]=*(x[2]+i); } for(i=0;i<3;i++) free(x[i]); } double gold(double a[],double b[],double eps,int n,double xx[]) {int i; double f1,f2,*x[2],ff,q,w; for(i=0;i<2;i++) x[i]=(double *)malloc(n*sizeof(double)); for(i=0;i {*(x[0]+i)=a[i]+*(b[i]-a[i]); *(x[1]+i)=a[i]+*(b[i]-a[i]); } f1=objf(x[0]); f2=objf(x[1]); do {if(f1>f2) {for(i=0;i {b[i]=*(x[0]+i); *(x[0]+i)=*(x[1]+i); } f1=f2; for(i=0;i *(x[1]+i)=a[i]+*(b[i]-a[i]); f2=objf(x[1]); } else { for(i=0;i {a[i]=*(x[1]+i); *(x[1]+i)=*(x[0]+i);} f2=f1; for(i=0;i *(x[0]+i)=a[i]+*(b[i]-a[i]); f1=objf(x[0]); } q=0; for(i=0;i q=q+(b[i]-a[i])*(b[i]-a[i]); w=sqrt(q); }while(w>eps); for(i=0;i xx[i]=*(a[i]+b[i]); ff=objf(xx); for(i=0;i<2;i++) free(x[i]); return(ff); } double oneoptim(double x0[],double s[],double h0,double epsg,int n,double x[]) {double *a,*b,ff; a=(double *)malloc(n*sizeof(double)); b=(double *)malloc(n*sizeof(double)); jtf(x0,h0,s,n,a,b); ff=gold(a,b,epsg,n,x); free(a); free(b); return (ff); } double powell(double p[],double h0,double eps,double epsg,int n,double x[]) {int i,j,m; double *xx[4],*ss,*s; double f,f0,f1,f2,f3,fx,dlt,df,sdx,q,d; ss=(double *)malloc(n*(n+1)*sizeof(double)); s=(double *)malloc(n*sizeof(double)); for(i=0;i {for(j=0;j<=n;j++) *(ss+i*(n+1)+j)=0; *(ss+i*(n+1)+i)=1; } for(i=0;i<4;i++) xx[i]=(double *)malloc(n*sizeof(double)); for(i=0;i *(xx[0]+i)=p[i]; for(;;) {for(i=0;i {*(xx[1]+i)=*(xx[0]+i); x[i]=*(xx[1]+i); } f0=f1=objf(x); dlt=-1; for(j=0;j {for(i=0;i {*(xx[0]+i)=x[i]; *(s+i)=*(ss+i*(n+1)+j); } f=oneoptim(xx[0],s,h0,epsg,n,x); df=f0-f; if(df>dlt) {dlt=df; m=j; } } sdx=0; for(i=0;i sdx=sdx+fabs(x[i]-(*(xx[1]+i))); if(sdx {free(ss); free(s); for(i=0;i<4;i++) free(xx[i]); return(f); } for(i=0;i *(xx[2]+i)=x[i]; f2=f; for(i=0;i {*(xx[3]+i)=2*(*(xx[2]+i)-(*(xx[1]+i))); x[i]=*(xx[3]+i); } fx=objf(x); f3=fx; q=(f1-2*f2+f3)*(f1-f2-dlt)*(f1-f2-dlt); d=*dlt*(f1-f3)*(f1-f3); if((f3 {if(f2<=f3) for(i=0;i *(xx[0]+i)=*(xx[2]+i); else for(i=0;i *(xx[0]+i)=*(xx[3]+i); } else {for(i=0;i {*(ss+(i+1)*(n+1))=x[i]-(*(xx[1]+i)); *(s+i)=*(ss+(i+1)*(n+1)); } f=oneoptim(xx[0],s,h0,epsg,n,x); for(i=0;i *(xx[0]+i)=x[i]; for(j=m+1;j<=n;j++) for(i=0;i *(ss+i*(n+1)+j-1)=*(ss+i*(n+1)+j); } } } void main() {double p[]={1,2}; double ff,x[2]; ff=powell(p,,,,2,x); printf("x[0]=%f,x[1]=%f,ff=%f\n",x[0],x[1],ff); getchar(); } 5. 复合形法 复合行法基本思想:在可行域中选取K个设计点(n+1≤K≤2n)作为初始复合形的顶点。比较各顶点目标函数值的大小,去掉目标函数值最大的顶点(称最坏点),以坏点以外其余各点的中心为映射中心,用坏点的映射点替换该点,构成新的复合形顶点。反复迭代计算,使复合形不断向最优点移动和收缩,直至收缩到复合形的顶点与形心非常接近,且满足迭代精度要求为止。 题目:求函数f(x)=(x1-5)*(x1-5)+4*(x2-6)*(x2-6)的最优点,约束条件为g1(x)=64-x1*x1-x2*x2≤0;g2(x)=x2-x1-10≤0;g3(x)=x1-10≤0;收敛精度ε自定义; 源程序代码及结果: #include <> #include <> #include <> #include <> #define E0 1e-5 /*复合形法收敛控制精度*/ double **apply(int,int); /*申请矩阵空间*/ double f(double *); /*目标函数*/ double *g(double *); /*约束函数*/ bool judge(double *); /*可行点的判断*/ int main() { int n,k; int i,j,k1; int l; double temporary; double restrain; /*收敛条件*/ double reflect; /*反射系数*/ srand((unsigned)time(NULL)); printf("请输入目标函数的维数 n:"); /*输入已知数据*/ 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("请输入选定的第一个可行点 x1(包含%d 个数):",n); for(i=0;i scanf("%lf",*x+i); printf("请输入初选变量的下限 a(包含%d 个数):",n); for(i=0;i printf("请输入初选变量的上限 b(包含%d 个数):",n); for(i=0;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 for(j=i+1;j 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 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 goto L2; } else if(reflect<=1e-10) { for(i=0;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