参考书目:机械最优设计技术,孟兆明 常德功
这本5元钱买的书,是无价宝,这钱不值钱的年代,买书最便宜
0.618是什么?其实就是步长。
有些函数是连续的,有导数的,某个区间里,还有极值,0.618法可以用,我们还可以用梯度下降法,或者其他可以求导的方法,但是如果某个区间有极值,不能求导,0.618法就可以用,看来这是个好方法,实现它,作个记录。
c#代码实现:
// min f(X)
//f(x)=x^2-10*x+8;
我们尝试找上面函数极值区间的极值,请参考上一节,找极值区间,我们就用这个极值存在的区间,找极值
float huangjinfengefa找极值结束条件 = 0.1f;
private void button黄金分割_Click(object sender, EventArgs e)
{
if (glob.X != 0 && glob.Y != 0)
{
float a = glob.Y;//a,b是找到的极值区间
float b = glob.X;
if (glob.X < glob.Y) { a = glob.X; b = glob.Y; }//a小,b大
float x1 = (float)(b - 0.618*(b - a));
float f1 = func(x1);
float x2 = (float)(a+0.618 * (b - a));
float f2 = func(x2);
if (Math.Abs(b - a) <= huangjinfengefa找极值结束条件) return;
diedaihuangjinfenge(ref f1, ref f2, ref x1, ref x2, ref a, ref b);//迭代黄金分割
}
}
float globmin = 0; float globminx = 0;
void diedaihuangjinfenge(ref float F1,ref float F2,ref float X1,ref float X2,ref float A,ref float B)
{
if (F1 < F2)//值大的一边干掉,找最小值
{
B = X2;
X2 = X1;
F2 = F1;
X1 = (float)(B - 0.618 * (B - A));
F1 = func(X1);
}
else
{
A = X1;
X1 = X2;
F1 = F2;
X2 = (float)(A + 0.618 * (B - A));
F2 = func(X2);
}
if (Math.Abs(B - A) <= huangjinfengefa找极值结束条件)
{
if (F1 < F2)
{
globmin = F1;
globminx = X1;
}
else
{
globmin = F2;
globminx = X2;
}
return;
}
diedaihuangjinfenge(ref F1,ref F2,ref X1,ref X2,ref A,ref B);
}
调试中,出现一个问题,如果这里没有这个return;程序就会挂掉,可以试试看!
前面总觉的自己用迭代已经很熟练了,不怎么用return的,在这里翻车!哈哈!