机械优化设计实验报告
《 机械优化设计 》
实验报告
目录
1、进退法确定初始区间 ................................................................................. 错误! 未定义书签。
1、1 进退法基本思路 ............................................................................. 错误! 未定义书签。
1、2 进退法程序框图误错ﻩ 错误! 未定义书签。
1、3 题目误错ﻩ 错误! 未定义书签。
1、4 源程序代码及运行结果误错ﻩ 错误! 未定义书签。
2、黄金分割法 ................................................................................................. 错误! 未定义书签。
2、2 黄金分割法流程图误错ﻩ 错误! 未定义书签。
2、3 题目误错ﻩ 错误! 未定义书签。
2、4 源程序代码及结果 ......................................................................... 错误! 未定义书签。
3、牛顿型法误错ﻩ 错误! 未定义书签。
3、1牛顿型法基本思路 ......................................................................... 错误! 未定义书签。
3、2 阻尼牛顿法得流程图 ................................................................................................. 4 3、3 题目 ............................................................................................... 错误! 未定义书签。
3、4 源程序代码及结果误错ﻩ 错误! 未定义书签。
4、鲍威尔法误错ﻩ 错误! 未定义书签。
4、1 鲍威尔法基本思路误错ﻩ 错误! 未定义书签。
4、2 鲍威尔法流程图误错ﻩ 错误! 未定义书签。
4.3 题目误错ﻩ 错误! 未定义书签。
4、4 源程序代码及结果 ....................................................................... 错误! 未定义书签。
5、 复合形法误错ﻩ 错误! 未定义书签。
5、1 复合行法基本思想 ......................................................................... 错误! 未定义书签。
5、3 源程序代码及结果 ......................................................................... 错误! 未定义书签。
6、 外点惩罚函数法误错ﻩ 错误! 未定义书签。
6、1 解题思路:误错ﻩ 错误! 未定义书签。
6、2 流程框图误错ﻩ 错误! 未定义书签。
6、3 题目 ............................................................................................... 错误! 未定义书签。
6、4 源程序代码及结果 ......................................................................... 错误! 未定义书签。
7、机械设计实际问题分析 ............................................................................. 错误! 未定义书签。
7、2计算过程如下误错ﻩ 错误! 未定义书签。
7、3 源程序编写误错ﻩ 错误! 未定义书签。
8、报告总结误错ﻩ 错误! 未定义书签。
1 、进退法确定初始区间 1 、1
进退法基本思路 :
按照一定得规则试算若干个点,比较其函数值得大小,直至找到函数值按“高—低-高”变化得单峰区间。
1 、2 进退法程序框图
1、3 题目: :用进退法求解函数 得搜索区间
1 、4 源程序代码及运行结果 #include <stdio、h〉 #include <math、h〉 main() {
;3af,2af,3a,2a,0=1a,3y,2y,1y,0h,h taolfﻩ scanf("h0=%f,y1=%f”,&h0,&y1);
h=h0;a2=h;y2=a2*a2-7*a2+10;
)1y>2y( fiﻩ {ﻩ
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;
)2y〈3y( fiﻩ {
;pool otogﻩ }
esleﻩ,2a,1a,"n\f%=3y,f%=2y,f%=1y,f%=3a,f%=2a,f%=1a”(ftnirpﻩﻩa3,y1,y2,y3); } 搜索区间为0
6 2 、黄金分割法 2、1 黄金分割法基本思路 :
通过不断得缩短单峰区间得长度来搜
索极小点得一种有效方法。按() 缩小
比较大小
确定取舍区间。
2 、2 黄金分割法流程图
2 、3
题目 :
对函数,给定搜索区间时,试用黄金分割法求极小点
2 、4 源程序代码及结果: :
f=inline(’x^2—7*x+9")
a=0;b=8;eps=0、001;
a1=b-0、618*(b—a);y1=f(a1);
a2=a+0、618*(b—a);y2=f(a2);
while(abs(b-a)>eps)
if(y1〉=y2)
a=a1;
a1=a2;
y1=y2;
a2=a+0、618*(b-a);
y2=f(a2);
else
b=a2;a2=a1;y2=y1;
a1=b-0、618*(b-a);
y1=f(a1);
end
end
xxx=0、5*(a+b)
f =
Inline function:
f(x)
= x^2—7*x+9 xxx =
3、4997 3 3 、牛顿型法
3 、1 牛顿型法基本思路 : : 在邻域内用一个二次函数
来近似代替原目标函数,并将 得极小点作为对目标函数求优得下一个迭代点.经多次迭代,使之逼近目标函数得极小点。
3 、2 阻尼牛顿法得流程图 :
3 、3 题目 :
用牛顿阻尼法求函数得极小点 3 、4 源程序代码及结果: :
k=0;
ptol=1、0e-5;
xk=input(’input x0:’)
itcl=[1;1];
while norm(itcl)>=ptol
f1=[4*xk(1,1)^3—24*xk(1,1)^2+50*xk(1,1)—4*xk(2,1)-32;—4*xk(1,1)+8*xk(2,1)];
G=[12*xk(1,1)^2—48*xk(1,1)+50,-4;-4,8];
dk=-inv(G)*f1; a=-(dk"*f1)/(dk’*G*dk);
xk=xk+a*dk;
开始给定结束0, x2 1[ ( )] ( )k k kf f d x x1:min ( )k k kkk kkf x x dx d1 k k x x* 1 k x x否是1 k k 0 k
itcl=a*dk;
k=k+1;
end
f=(xk(1,1)—2)^4+(xk(1,1)-2*xk(2,1))^2;
fprintf('\n ÓÃ×èÄáÅ£¶Ù·¨µü´ú %d ´ÎºóµÃµ½ ¼«Ð¡µã x*¼°¼«Ð¡Öµ f Ϊ:\n’,k);
disp(xk);
disp(f);
结果显示:input x0:[1;1]
用阻尼牛顿法迭代 27 次后得到 极小点 x*及极小值 f 为:
2、0000
1、0000 1、3270e—019 4 、鲍威尔法
4 、1 鲍威尔法基本思路 : : 在不用导数得前提下,在迭代中逐次构造 G得共轭方向。
4 、2 鲍威尔法流程图: :
4。3 题目 : 求函数f(x)= x[0]*x[0]+x[1]*x[1]-x[0]*x[1]—10*x[0]—4*x[1]+60得最优点,收敛精度ε=0、001 4 、4 源程序代码及结果 :
#include ”stdio、h" #include "stdlib、h" #include "math、h" 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〈n;i++)
*(x[0]+i)=x0[i]; f1=objf(x[0]); for(i=0;i<n;i++) *(x[1]+i)=*(x[0]+i)+h*s[i]; f2=objf(x[1]); if(f2>=f1) {h=-h0; for(i=0;i〈n;i++) *(x[2]+i)=*(x[0]+i); f3=f1; for(i=0;i〈n;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<n;i++) *(x[2]+i)=*(x[1]+i)+h*s[i]; f3=objf(x[2]);
if(f2〈f3) break; else { for(i=0;i〈n;i++) {*(x[0]+i)=*(x[1]+i); *(x[1]+i)=*(x[2]+i); } f1=f2; f2=f3; } } if(h<0) for(i=0;i<n;i++)
{a[i]=*(x[2]+i); b[i]=*(x[0]+i); } else for(i=0;i〈n;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<n;i++)
{*(x[0]+i)=a[i]+0、618*(b[i]—a[i]);
*(x[1]+i)=a[i]+0、382*(b[i]-a[i]); } f1=objf(x[0]); f2=objf(x[1]); do {if(f1>f2)
{for(i=0;i<n;i++)
{b[i]=*(x[0]+i); *(x[0]+i)=*(x[1]+i); } f1=f2; for(i=0;i<n;i++)
*(x[1]+i)=a[i]+0、382*(b[i]—a[i]); f2=objf(x[1]); } else { for(i=0;i<n;i++) {a[i]=*(x[1]+i); *(x[1]+i)=*(x[0]+i);} f2=f1; for(i=0;i<n;i++)
*(x[0]+i)=a[i]+0、618*(b[i]-a[i]); f1=objf(x[0]); } q=0; for(i=0;i〈n;i++)
q=q+(b[i]—a[i])*(b[i]-a[i]); w=sqrt(q); }while(w〉eps); for(i=0;i<n;i++)
xx[i]=0、5*(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<n;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<n;i++)
*(xx[0]+i)=p[i]; for(;;)
{for(i=0;i<n;i++)
{*(xx[1]+i)=*(xx[0]+i); x[i]=*(xx[1]+i); } f0=f1=objf(x); dlt=-1; for(j=0;j<n;j++)
{for(i=0;i<n;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<n;i++)
sdx=sdx+fabs(x[i]—(*(xx[1]+i))); if(sdx<eps) {free(ss); free(s); for(i=0;i〈4;i++)
free(xx[i]); return(f); } for(i=0;i〈n;i++)
*(xx[2]+i)=x[i]; f2=f; for(i=0;i<n;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=0、5*dlt*(f1-f3)*(f1-f3); if((f3<f1)||(q〈d))
{if(f2〈=f3) for(i=0;i<n;i++)
*(xx[0]+i)=*(xx[2]+i); else for(i=0;i<n;i++) *(xx[0]+i)=*(xx[3]+i); } else {for(i=0;i<n;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<n;i++) *(xx[0]+i)=x[i]; for(j=m+1;j〈=n;j++)
for(i=0;i〈n;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,0、3,0、001,0、0001,2,x); printf("x[0]=%f,x[1]=%f,ff=%f\n",x[0],x[1],ff); getchar(); }
5 、 复合形法
5 、1 复合行法基本思想 :
在可行域中选取 K 个设计点 (n+1≤K≤2n)作为初始复合形得顶点。比较各顶点目标函数值得大小,去掉目标函数值最大得顶点(称最坏点),以坏点以外其余各点得中心为映射中心,用坏点得映射点替换该点,构成新得复合形顶点。
反复迭代计算,使复合形不断向最优点移动与收缩,直至收缩到复合形得顶点与形心非常接近,且满足迭代精度要求为止.
5 、2 题目: 求函数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;收敛精度ε自定义; 5 、3 源程序代码及结果:
#include 〈stdio、h>
#include 〈stdlib、h>
#include 〈time、h>
#include <math、h>
#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<n;i++)
scanf("%lf",*x+i);
printf("请输入初选变量得下限 a(包含%d 个数):",n);
for(i=0;i<n;i++) scanf("%lf”,a+i);
printf("请输入初选变量得上限 b(包含%d 个数):",n);
for(i=0;i<n;i++)
scanf("%lf”,b+i);
printf("输出输入结果为:\nn=%d,k=%d,x1=(",n,k); /*输出已知数据*/
for(i=0;i<n—1;i++)
printf(”%、5lf ”,*(*x+i));
printf(”%、5lf)\na=(",*(*x+n-1)); for(i=0;i<n-1;i++)
printf(”%f ”,*(a+i));
printf(”%、5lf),b=(",*(a+n-1));
for(i=0;i<n—1;i++)
printf("%f ”,*(b+i));
printf("%、5lf)\n",*(b+n-1));
L1: for(i=1;i<k;i++) /*随机得到其余(k-1)个可行点*/
ﻩ for(j=0;j<n;j++)
ﻩ
*(*(x+i)+j)=*(a+j)+(double)(rand()%10000)/10000*(*(b+j)-*(a+j));
ﻩ l=1;
for(i=1;i〈k;i++) /*找出可行点得个数 l,并把可行点放在前 l 个位置上*/
ﻩ if(judge(*(x+i)))
{ﻩ ﻩ
for(j=1;j<k;j++)
ﻩ
ﻩ if(!judge(*(x+j)))
ﻩﻩ {
for(k1=0;k1<n;k1++)
{ﻩﻩﻩﻩﻩ ﻩ
ﻩﻩﻩ temporary=*(*(x+i)+k1);
ﻩﻩ (*(*ﻩ;)1k+)j+x(*(*=)1k+)i+xﻩ ﻩ
ﻩﻩ (*(*
;yraropmet=)1k+)j+xﻩﻩ ﻩ
ﻩﻩ
}
ﻩ
;kaerbﻩﻩ
} ﻩﻩﻩﻩ
ﻩﻩ
;++lﻩ
}
ﻩ 排小到大从值数函标目按点行可个 l 前把*/ )++i;1-l<i;0=i(rofﻩ序*/
)++j;l<j;1+i=j(rofﻩﻩ ﻩﻩ
)))j+x(*(f〈))i+x(*(f(fiﻩﻩ
ﻩ
ﻩ for(k1=0;k1<n;k1++)
{ﻩ ﻩﻩ
ﻩﻩ temporary=*(*(x+i)+k1);
(*(*ﻩ ﻩ;)1k+)j+x(*(*=)1k+)i+xﻩ(*(*ﻩﻩﻩ ﻩ;yraropmet=)1k+)j+xﻩ
ﻩﻩﻩﻩ }
ﻩ
/*心中点行可求*/ )++i;n〈i;0=i(rofﻩﻩ
ﻩﻩ
*(x_c+i)=0;
ﻩﻩ
)++i;l<i;0=i(rofﻩ ﻩﻩ )++j;n<j;0=j(rofﻩﻩ
(*ﻩ;)j+)i+x(*(*=+)j+c_xﻩ
ﻩ
ﻩ
)++i;n<i;0=i(rofﻩ
ﻩ
ﻩﻩ
*(x_c+i)/=l;
ﻩ ﻩﻩﻩ
if(!judge(x_c)) /*判断可行点中心就是否可行*/
ﻩ
ﻩ {
ﻩ
ﻩ
ﻩ for(i=0;i<n;i++)
ﻩ
ﻩﻩ
{ﻩ
ﻩﻩﻩ
ﻩ (* ;)i+)1-l+x(*(*=)i+aﻩ*(b+i)=*(x_c+i);
ﻩﻩ
ﻩ
}
ﻩﻩ
ﻩﻩﻩ goto L1;
ﻩﻩﻩ
}
ﻩﻩﻩ
esleﻩ ﻩﻩ
{ﻩ
ﻩ /*化行可点行可不将*/ )++i;k<i;l=i(rofﻩ
ﻩﻩﻩ odﻩﻩ
ﻩ
ﻩﻩ
ﻩﻩ {
ﻩ
for(j=0;j<n;j++)
ﻩ
ﻩ (*(* ﻩ)j+)i+x(*(*(*5、0+)j+c_x(*=)j+)i+xﻩ-*(x_c+j));
} ﻩﻩﻩﻩ ﻩﻩﻩ
ﻩ
elihwﻩ ﻩ
ﻩﻩ !(ﻩ ﻩ;)))i+x(*(egdujﻩL2:
/*序排小到大从值数函标目按点行可将*/ )++i;1-k〈i;0=i(rofﻩ ﻩ
ﻩ
ﻩﻩ for(j=i+1;j<k;j++)
ﻩ
)))j+x(*(f<))i+x(*(f(fiﻩﻩ
ﻩ
ﻩ
ﻩﻩ
)++1k;n〈1k;0=1k(rofﻩ ﻩ ﻩﻩﻩﻩ
ﻩﻩ
{ﻩ
ﻩﻩ
ﻩﻩ temporary=*(*(x+i)+k1);
ﻩﻩ
ﻩ
ﻩ
ﻩﻩ *(*(x+i)+k1)=*(*(x+j)+k1);
ﻩ
ﻩﻩ (*(*ﻩ;yraropmet=)1k+)j+xﻩ
ﻩﻩ
}ﻩﻩﻩ ﻩﻩﻩ
ﻩ
ﻩﻩﻩﻩ
/*件条敛收求*/ ;0=niartserﻩ
ﻩ
ﻩ
ﻩ
ﻩ for(i=0;i<k;i++)
ﻩ
ﻩﻩ
ﻩ
-k+x(*(f-))i+x(*(f(=+niartserﻩ1)))*(f(*(x+i))-f(*(x+k—1)));
ﻩﻩ
ﻩ
ﻩ
;)niartser*)1-k(/0、1(trqs=niartserﻩ
ﻩ
ﻩ
ﻩ if(restrain<E0) /*判断收敛条件*/
ﻩ
ﻩﻩ
ﻩﻩ
{
ﻩ
ﻩﻩ
ﻩﻩﻩﻩﻩ printf("\n 求得约束最优点为:( ”);
ﻩ ﻩﻩﻩﻩﻩﻩ
)++i;n<i;0=i(rofﻩﻩ
ﻩ
ﻩﻩﻩ printf(”%。5f ”,*(*(x+k—1)+i));
ﻩ
ﻩ
ﻩﻩﻩﻩ
ﻩﻩ printf(")\n 目标函数得最优解为:%。5f\n",f(*(x+k-1)));
ﻩ
ﻩﻩ ﻩﻩﻩ
ﻩ
;0 nruterﻩﻩ
ﻩ ﻩﻩﻩﻩﻩﻩ
}
ﻩ
ﻩ
ﻩ
esleﻩ ﻩ
ﻩ
ﻩ
{ ﻩﻩﻩL3:心中得点顶个)1-k(得外 x*点坏最去除算计*/ )++i;n〈i;0=i(rofﻩ*/
ﻩ
ﻩ
ﻩﻩ
*(x_c+i)=0;
ﻩ
ﻩ
ﻩ)++i;k<i;1=i(rofﻩ
ﻩ
ﻩ
ﻩﻩ
ﻩﻩﻩ for(j=0;j<n;j++)
ﻩ
ﻩ (*ﻩﻩ ﻩﻩﻩ ﻩ ;)j+)i+x(*(*=+)j+c_xﻩ
ﻩﻩﻩ
ﻩﻩ ﻩ )++i;n<i;0=i(rofﻩ
ﻩﻩ
ﻩ
ﻩ
ﻩ
ﻩ (* ;1-k=/)i+c_xﻩ ﻩ
ﻩﻩﻩﻩﻩﻩ
ﻩ
reflect=1、3;
L4:
/*点射反求*/ )++i;n<i;0=i(rofﻩ ﻩ ﻩﻩﻩﻩﻩﻩ ﻩﻩﻩﻩ (* ;))i+x*(*—)i+c_x(*(*tcelfer+)i+c_x(*=)i+r_xﻩ
ﻩﻩﻩﻩﻩﻩ ﻩﻩ ﻩ ))r_x(egduj!(fiﻩ
ﻩﻩﻩ
ﻩ
ﻩ
{
ﻩﻩ
ﻩﻩ ﻩ;5、0=*tcelferﻩ
ﻩ
ﻩ
ﻩ;4L otogﻩ
ﻩ
}ﻩ ﻩﻩﻩﻩﻩ ﻩﻩ
ﻩﻩ
ﻩ
fi esleﻩ ﻩ
ﻩ
ﻩ (ﻩ ))x*(f〈)r_x(fﻩ
ﻩﻩ
{ ﻩﻩﻩﻩﻩ
ﻩ ﻩﻩﻩﻩﻩ
for(i=0;i<n;i++)
*(*x+i)=*(x_r+i);
ﻩﻩ
ﻩﻩ
goto L2;
ﻩ
ﻩ
}ﻩ
ﻩ
ﻩ
)01-e1=〈tcelfer(fi esleﻩ
ﻩﻩﻩ
{
ﻩﻩﻩ ﻩ ;)i+)1+x(*(*=)i+x*(* )++i;n<i;0=i(rofﻩﻩ
ﻩﻩﻩﻩ
ﻩ ;3L otogﻩ
ﻩ
}ﻩ ﻩ
ﻩﻩ
esleﻩﻩ
ﻩ ﻩﻩﻩ
{
ﻩ
;5、0=*tcelferﻩ
ﻩ
ﻩﻩ
;4L otogﻩﻩ ﻩﻩ
ﻩﻩﻩ
}ﻩ ﻩ
ﻩﻩﻩﻩ
}
ﻩ
ﻩﻩ }
}
double **apply(int row,int col)
/*申请矩阵空间*/
{
;i tniﻩ
;))elbuod(foezis,loc*wor(collac)*elbuod(=x* elbuodﻩ
double **y=(double **)calloc(row,sizeof(double *));
if(!x || !y)
{ printf(”内存分配失败!”);
exit(1);
}
)++i;wor<i;0=i(rofﻩ(*
;y nruter ;loc*i+x=)i+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));
)p!(fiﻩ
{ ﻩ
;)”!败失配分存内”(ftnirpﻩﻩ
;)1(tixeﻩ}
*p=64—(*x)*(*x)—(*(x+1))*(*(x+1));
*(p+1)=*(x+1)-*x-10;
(*
;01—x*=)2+pﻩ
return p;
}
bool judge(double *x) /*可行点得判断*/
{
int i;
double *p=(double *)calloc(3,sizeof(double));
p=g(x);
for(i=0;i<3;i++)
fiﻩ ﻩ
(*(p+i)〉0)
break;
if(i==3)
return true;
else return false;
}
6、 外点惩罚函数法 6、 、1 解题思路:外点法就是从可行域得外部构造一个点序列去逼近原约束问题得最优解。外点法可以用来求解含不等式与等式约束得优化问题。外点惩罚函数得形式为:
6 、2
流程框图: :
2 21 1( , ) ( ) max[0, ( )] [ ( )]m li ji jr f r g r h x x x x
6 、3 题目: 求函数 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;收敛精度ε=0、00001;
6 、4 源程序代码及结果 :
#include <stdio、h> #include〈iostream、h〉 #include〈math、h> double lamta[10]={0, 1、0 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,1};//鲍威尔方法初始化方向,线性无关 double lamta1[3]={0, 0 , 0};//暂存新得搜索方向 double x1[4]={0, 0 ,0, 0 };//x1到 x3 用于存储各共轭方向得点 double x2[4]={0, 0 ,0, 0 }; double x3[4]={0, 0 ,0, 0 }; double x4[4]={0, 0 ,0, 0 };//x4用于中间判断 double x5[4]={0, 0 ,0, 0 };//x5 用存放于更换方向后产生得新点 int m=0;//标志 double x_[4]={0, 0, 0, 0};//暂存鲍威尔最优解 double x0[4]={0, 2, 2 , 2};//初值
double c=10;//递减系数
double e=0、00001;//精度控制 double r0=1;//初始惩罚因子 double r=1; //函数声明部分 void Powell(double r);
//鲍威尔方法函数 double fxy(double x1,double x2,double x3,double r);
//待求函数 double ysearch(double x);
//一维搜索得目标函数 void search(double &a,double &b,double h);
//区间搜索 double
yellowcut(double &a,double &b);
//黄金分割 void sort(double *p,int size);//选择法排序 void main()
//约束优化方法主函数入口 {
cout〈〈”请输入精度”〈〈endl;
cin>〉e; changyan:Powell(r);
double cmpare[4];
int flag1=0;
for (int i=1;i〈=3;i++)
{
cmpare[i]=x_[i]—x0[i];
if (fabs(cmpare[i])<e)
{flag1++;}
}
if (flag1==3)
{
printf(”x1=%lf
x2=%lf\n",x_[1],x_[2]); //
cout〈〈"最优解为:"<〈"x1=”〈〈x_[1]<<”
"〈<”x2="<〈x_[2]〈<"
"〈<"x3="<〈x_[3]<〈endl ;
cout〈<"最小值为"〈〈fxy(x_[1],x_[2],x_[3],r)〈〈endl;
}
else
{
for (int j=1;j<=3;j++)
{
x0[j]=x_[j];
}
r=c*r;
goto changyan;
} } //子函数定义部分 double fxy(double x1,double x2,double x3,double r)//待求函数 {
double m,n,p;
m=((64—x1*x1-x2*x2)>0)?(64-x1*x1—x2*x2):0;
n=((x2-x1-10)>0)?(x2-x1-10):0;
p=((x1-10)>0)?(x1—10):0;
return
//惩罚函数 (x1-5)*(x1—5)+4*(x2-6)*(x2-6)+r*(m*m+n*n+p*p)+r*(x3*x3); } void Powell(double r)
//鲍威尔方法函数定义 {
double det=0、0001;
//迭代精度
int k; my1:
for (k=1;k<=3;k++)
{
m=3*k-2;
double a=0,b=0,xo=0;
search(a,b,1);
//完成区间搜索
double temp;
temp=yellowcut(a,b);//黄金分割法
int n=3*k-2;
for (int i=1;i<=3;i++)
{
switch (k)
{
case 1:x1[i]=x0[i]+temp*lamta[n++];break;
case 2:x2[i]=x1[i]+temp*lamta[n++];break;
case 3:x3[i]=x2[i]+temp*lamta[n++];break;
default :break;
}
}
}
double cmp[4];
int flag=0;
for (int i=1;i〈=3;i++)
{
cmp[i]=x3[i]-x0[i];
if (fabs(cmp[i])<det)
{flag++;}}
if (flag==3)
//找到最优解
{
x_[1]=x3[1];
x_[2]=x3[2];
x_[3]=x3[3];
}
else
{
double fy[4];
fy[0]=fxy(x0[1],x0[2],x0[3],r);
fy[1]=fxy(x1[1],x1[2],x1[3],r);
fy[2]=fxy(x2[1],x2[2],x2[3],r);
fy[3]=fxy(x3[1],x3[2],x3[3],r); double fyy[3];
for (int ii=0;ii<3;ii++)
{fyy[ii]=fy[ii]—fy[ii+1];}
sort(fyy,3);
for (ii=1;ii〈=3;ii++)
{x4[ii]=2*x3[ii]—x0[ii];}
double f0,f3,f4;
f0=fy[0];
f3=fy[3];
f4=fxy(x4[1],x4[2],x4[3],r);
if ((f0+f4—2*f3)/2〉=fyy[2])
{
if (f3〈f4)
{
for (int t=1;t〈=3;t++)
{x0[t]=x3[t];}
}
else
{
for (int t=1;t<=3;t++)
{x0[t]=x4[t];
}}
goto my1;
}
else{
for (int t=0;t〈3;t++)
{lamta1[t]=x3[t+1]-x0[t+1];}
m=0;
//switch 标志!
double aa=0,bb=0;
search(aa,bb,1);
double temp1;
temp1=yellowcut(aa,bb);
for (int i=1;i〈=3;i++)
{x5[i]=x3[i]+temp1*lamta1[i-1];}
for (i=1;i〈=3;i++)
{x0[i]=x5[i];}
for (i=1;i〈=6;i++)
{lamta[i]=lamta[i+3];}
for (i=1;i<=3;i++)
{
lamta[6+i]=lamta1[i—1];}
goto my1; }}} double ysearch(double x)
//一维搜索得目标函数 { switch (m)
{ case 1:
return fxy(x0[1]+x*lamta[m],x0[2]+x*lamta[m+1],x0[3]+x*lamta[m+2],r);break; case 4:
return fxy(x1[1]+x*lamta[m],x1[2]+x*lamta[m+1],x1[3]+x*lamta[m+2],r);break; case 7:
return fxy(x2[1]+x*lamta[m],x2[2]+x*lamta[m+1],x2[3]+x*lamta[m+2],r);break; case 0:
return fxy(x3[1]+x*lamta1[0],x3[2]+x*lamta1[1],x3[3]+x*lamta1[2],r);break;//更改方向后得一维搜索 default:return 0; break; } } void search(double &a,double &b,double h)
//区间搜索 {double a1,a2,a3,y1,y2,y3; h=1; a1=a,y1=ysearch(a1); a2=a+h,y2=ysearch(a2); if(y2〉=y1){
h=-h,a3=a1,y3=y1;
a1=a2,y1=y2,a2=a3,y2=y3;} a3=a2+h,y3=ysearch(a3); while(y3<=y2){
h=2*h;
a1=a2,y1=y2,a2=a3,y2=y3;
a3=a2+h,y3=ysearch(a3); } if(h〈0)a=a3,b=a1; else a=a1,b=a3;} double
yellowcut(double &a,double &b){
double e;
//黄金分割法求解
e=0、001;
double c,fc;
c=a+0、382*(b-a);
fc=ysearch(c);
double d,fd;
double xo;
d=a+0、618*(b-a);
fd=ysearch(d); label2: if (fc<=fd)
{b=d;
d=c;
fd=fc;
c=a+0、382*(b—a);
fc=ysearch(c);}
else
{a=c;
c=d;
fc=fd;
d=a+0、618*(b-a);
fd=ysearch(d);}
if ((b—a)〈=e)
{xo=(a+b)/2;}
else
goto label2;
return xo; } void sort(double *p,int size){//选择法排序
int i,j;
double k;
for(i=0;i〈size-1;i++)
for(j=i+1;j〈size;j++)
if(*(p+i)>*(p+j)){k=*(p+i);*(p+i)=*(p+j);*(p+j)=k;} }
7 、机械设计实际问题分析
7、1 题目 : 图 示 为 一 对 称 得 两 杆 支 架 , 在 支 架 得 顶 点 承 受 一 个 载 荷 为2 2F F= =3 3 00 00 0 00 0
, ,支 支 架 之 间 得 水 平 距离 离
2 2B B= =1 1 52 20 0 m m, ,若 若 已 选 定 壁厚 厚T T= =2 2. . 5 m m钢 钢 管 ,密度 度p p= =8 83 30 00 0k kg g/ / m3 3, ,屈 屈 服点 点
, , 材 料 得 弹 性 模量 量
。
要 求 在 满 足 强 度 与 稳 定 性 条 件 下 设 计 最 轻 得 支 架 尺寸 寸. .
7 、2 计算过程如下: 解:计算压杆得临界柔度为:
,
由于支架为空心杆,失效形式主要为屈服,故计算稳定性用屈服极限公式。根据题意可得方程组:
,
代入整理得到内点混合惩罚函数法得标准形式为:
构建惩罚函数: kk k kr Xrx xx x r x r x r x x22 1 222122212221 ,5 . 246 . 96 86 . 84 )
(
, 取,
0005 . 0 2 24 73 . 1692 11 11 kkrx xx r xx
解得:
令迭代精度为:,由于函数就是 X 得2次方程,故不必判别函数值得相对变化量。
7 、3 源程序编写
#include <stdio、h> #include 〈math、h〉 double GetX3( double r) {
return (1-42*sqrt(r))*(0、21*sqrt(r)+0、01*r)/(168、172*sqrt(r)—38*r)+0、0025; } double GetX4( double r) { return (0、21*sqrt(r)+0、01*r)/(168、172*sqrt(r)-38*r);
} double F( double x3,double x4)
{
return 42、4315*(x3*x3-x4*x4); } main()
{
double x1=0,x2=0,x3,x4,r=1,c=0、01,m=0、0000001;
int i=1;
x3=GetX3(r);
x4=GetX4(r);
while(1)
{
printf(”迭代次数:%d\n”,i);
printf("r=%。12f\n",r);
printf("x1=%f\n”,x3);
printf("x2=%f\n",x4);
printf("\n");
r=c*r;
x1=x3;
x2=x4;
x3=GetX3(r);
x4=GetX4(r);
if((fabs(x1—x3)<=m)&&(fabs(x4-x2)<=m))
break;
i++;
}
printf("最优解为:\n");
printf("R=%f(单位:米)\n",x3);
printf("r=%f(单位:米)\n",x4);
printf(”最小体积V=%f(单位:立方米)\n",F(x3,x4));
return(0); }
用C语言编程计算,求得结果为: 最小外径R=3.749mm, 最小内径 r=1.249mm, 最小体积:v=530000 立方毫米 故满足强度与稳定性条件下最轻得支架尺寸约为外径 3。75mm,内径1。25mm。
8 、报告总结
通过这一段时间得学习我了解到机械优化设计就是以数学规划论为基础,以计算机为工具,一种自动寻优得先进得、现代得设计方法。根据设计所追求得性能目标,建立目标函数,在满足给定得各种约束条件下,寻求最优得设计方案.可见它就是非常经典得一门学科。再加上王卫荣老师系统全面科学得教授过程,更就是使这一学科魅力十足,强烈地吸引着我对它得深入学习与实践。
在课程学习过程中我明白了很多工程问题就是可以转化为数学模型并可以通过计算机求解。
同时了解了delphi得基本得使用技巧,并且复习了C语言与matlab编程相关知识,并将其应用到了约束随机法、惩罚函数法去求解问题,收获颇多。优化设计同时也教会了我如何追求“优”,同时使自己有能力、有办法“化"到优!
上一篇:信号与系统实验报告,(2)
下一篇:单片机实验报告2