机械优化设计实验报告(浙江理工大学)
机械优化设计实验
报告
班级:XXXX
姓名:XX
学号:XXXXXXXXXXX
一、 外推法
1、 实验原理
常用的一维优化方法都是通过逐步缩小极值点所在的搜索区间来求最优解的。一般情况下,我们并不知道一元函数f (X )极大值点所处的大概位置,所以也就不知道极值点所在的具体区域。由于搜索区间范围的确定及大小直接影响着优化方法的收敛速度及计算精度。因此,一维优化的第一步应首先确定一个初始搜索区间,并且在该区间内函数有唯一的极小值存在。该区间越小越好,并且仅存在唯一极小值点。
所确定的单股区间应具有如下性质:如果在[α1,α3]区间内任取一点α2,, α1f(α2)
2、 实验工具
C-Free3.5软件
3、 程序调试
#include
#include
#define f(x) 3*x*x-8*x+9 //定义函数
int main()
{
double a0,a1,a2,a3,f1,f2,f3,h;
printf(“a0=”,a0); //单谷区间起始点
scanf(“%lf”,&a0);
printf(“h=”,h); //起始的步长
scanf(“%lf”,&h);
a1=a0;
a2=a1+h;
f1=f(a0);
f2=f(a2);
if(f1>f2) //判断函数值的大小,确定下降方向
{
a3=a2+h;
f3=f(a3);
}
else
{
h=-h;
a3=a1;
f3=f1;
a1=a2;
f1=f2;
a2=a3;
f2=f3;
a3=a2+h;
f3=f(a3);
}
while(f3
断
{
h=2*h;
a1=a2;
f1=f2;
a2=a3;
f2=f3;
a3=a2+h;
f3=f(a3); //当不满足上述比较时,说明下降方向反向,继续进行判
}
printf(“a1=%lf,a3=%lf\n”,a1,a3);
printf(“[a1,a3]=[%lf,%lf]\n”,a1,a3); //输出区间
}
4、 调试结果
5、 总结与讨论
1) 当写成void main时会出现如下警告
改成int main警告消失。
二、 黄金分割法
1、 实验原理
在外推法确定了单股区间[α1,α3]的基础上去其中对称两点α2,α4,且满足
α2=α3−λ α3−α1
α4=α1+λ(α3−α1)
式中,λ位0~1的缩小系数。
计算点α2,α4的函数值,记f2=f(α2) ,f4=f(α4) ,并比较他们的大小,可能存在如下三种情况:
(1)f2
(2)f2>f4:此时必有极小值点α∈[α2, α3],应舍去区间[α1,α2],保留的区间长度为λl ,缩小后的新区间为[α2,α3];
(3)f2=f4:此时必有极小值点α∈[α2, α4],应舍去区间[α1,α2]或[α4,α3]。
经过比较取舍后,缩小后所得的新区建长度均为λl ,将区间端点重新命名为[α1,α3],就可以进行新一轮的比较,如此循环。
2、 实验工具
C-Free 3.5软件
3、 程序调试
#include
#include
#define f(x) 3*x*x-8*x+9
#define v 0.618 //黄金分割点
int main()
{
float a0,a1,a2,a3,a4,f0,f1,f2,f3,f4,b; //b收敛精度
puts("单谷区间 a1=");
scanf("%f",&a1);
puts("单谷区间 a3=");
scanf("%f",&a3);
puts("收敛精度 b=");
scanf("%.4f",b);
a2=a3-v*(a3-a1);
f2=f(a2);
a4=a1+v*(a3-a1);
f4=f(a4);
do
环
{
if(f2>f4)
{
a1=a2;
a2=a4;
f2=f4;
a4=a1+v*(a3-a1);
f4=f(a4);
}
else
{
a3=a4;
a4=a2;
f4=f2;
a2=a3-v*(a3-a1);
f2=f(a2);
}
}
while(abs(a3-a1)>b); //do-while循环,知道满足条件退出循//判断函数值大小,缩小比较区间
a0=(a3+a1)/2;
f0=f(a0);
printf("a0=%lf\n",a0); //输出结果
printf("f0=%lf\n",f0);
}
4、 调试结果
5、 总结与讨论
1) 要选择合适的循环嵌套语句,实现循环的同时判断;
2) 在执行
puts("单谷区间 a1=");
scanf("%f",&a1);
puts("单谷区间 a3=");
scanf("%f",&a3);
puts("收敛精度 b=");
scanf("%.4f",b);
语句时,注意在最后一个scanf 语句约束输入的位数,如在前面输入约束,
puts("单谷区间 a1=");
scanf("%.4f",&a1);
puts("单谷区间 a3=");
scanf("%.4f",&a3);
puts("收敛精度 b=");
scanf("%.4f",b);
如会出现程序如下错误:
如不输入约束,函数由于float 的精度位数太高,会陷入死循环,导致程序崩溃。如图所示:
三、 鲍威尔法
1、 实验原理
鲍威尔法——多维无约束优化算法是在无约束优化算法之一,首先选取一组共轭方向,从某个初始点出发,求目标函数在这些方向上的极小值点,然后以该点为新的出发点,重复这一过程直到获得满意解,其优点是不必计算目标函数的梯度就可以在有限步内找到极值点。鲍威尔法是以共轭方向为基础的收敛较快的直接法之一,是一种十分有效的算法。在无约束方法中许多算法都是以共轭方向作为搜索方向,它们具有许多特点。
根据构造共轭方向的原
理不同,可以形成不同的共轭方向法。
2、 实验工具
C-Free 3.5 软件
3、 程序调试
#include
#include
#include
double objf(double x[])//定义目标函数
{
}
void jtf(double x0[ ],double h0,double s[ ],intn,double a[ ],double b[ ]) {
int i; double *x[3],h,f1,f2,f3; for (i=0;i
if(f2>=f1) { h= -h0; for (i=0;i
}
} if(h
double gold(double a[],double b[],double eps,intn,double xx[])
{
int i; double f1,f2,*x[2],ff,q,w; for(i=0;i
f2=objf(x[1]); do {if(f1>f2) {for(i=0;ieps); for(i=0;i
}
for(i=0;i
doubleoneoptim(double x0[],double s[],double h0,double epsg,intn,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,doubleepsg,intn,double x[])
{
inti,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
*(ss+i*(n+1)+j)=0;
*(ss+i*(n+1)+i)=1;
}
for (i=0;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
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=0.5*dlt*(f1-f3)*(f1-f3);
if((f3
{
if(f2
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
for (i=0;i
*(ss+i*(n+1)+j-1)=*(ss+i*(n+1)+j);
}
}
}
int main() //主函数
{
double p[]={1,1};
doubleff,x[2];
ff=powell(p,0.3,0.001,0.0001,2,x);
printf("输出最优点及其目标函数值:\n");
printf("x[0]=%.4f,x[1]=%.4f,ff=%.4f\n",x[0],x[1],ff);
}
4、 调试结果
5、 总结与讨论
1) 鲍威尔法用C 语言来编写存在很大的难度,由于C 语言没有专属的矩阵运算和求导运算算法,所以又给编写鲍威尔法增加了很大难度,需要先定义矩阵的运算函数和求导的运算函数。因此,鲍威尔法编写的难点集中在了函数的编写,其主函数并不难。
2) 有程序框图可得鲍威尔法的基本算法结构如下:
do
{
do
{ 循环体 } While(判别式) ; If(判别式) 表达式1
elseif(判别式) 表达式2
else 语句
}
while(判别式) ;
机械优化设计问题
1、问题描述
现有一单级渐开线直齿圆柱齿轮减速器,其输入功率N=280kW,输入转矩n1=980r/min,传动比i=5。小齿轮为实体结构,大齿轮为腹板式结构(带有四个减轻孔),两齿轮各部分尺寸的符号如图所示:
原用常规设计方法的设计结果为:齿宽B=B2=13cm,小齿轮齿数z1=21,模数m0.8cm ,l1=42cm,ds1=12cm,ds2=16cm。先要求在保证承载能力的条件下,通过优选上述有关参数,使减速器的体积达到最小。
2、 建立目标函数
减速器的体积主要取决于内部零件的尺寸大小,在齿轮和轴的结构尺寸确定之后,箱体的尺寸将随之确定,因此将齿轮和轴的总体积达到最小作为优化目标。
减速器内部有两个齿轮和两根轴,为了简化计算,将轴视为光轴,则有
V =VS1+VS2+Vg1+Vg2
=π2π2π2π2π22 2 2 D2−D1ds1 l1+l2 +dsl+l+d−d+d−d−B2−C 21s1212s2π2−4(d0C) 4
式中:VS1,VS2——两轴体积,cm 3;
Vg1,Vg2——两齿轮体积,cm 3; ds1,ds2——两轴的直径,cm ;
l1,l2,l3——轴的长度,cm ; d1,d2——两齿轮的分度圆直径,cm ; m ——两齿轮的模数; B 1,B 2——两齿轮的宽度,近似取B 1=B2=B,cm ; 优化设计中的设计变量取为:
X =[x1, x2, x3, x4, x5, x6]T=[B, z1, m, l1, ds1, ds2]T
将目标函数整理后得到:
2222222f X =0.78539815(4.75x1x2x3+85x1x2x3−85x1x3+0.92x1x6−x1x5+0.8x1x2x3x4
2222−1.6x1x6x3+x4x5+x4x6+28x5+32x6)