1.黄金分割搜索算法又称0.618算法,我作为初学者把我理解体会分享输出供大家批评指正。
2.我以求单峰极大值为例:很明显下图的极大值的位置是5,接下来我来用0.618法求解出来。
3 .1 根据公式找两个点,将图形分成三部分:[a,x1],[x1,x2],[x2,b],第一步很容易理解,公式有很多类型,类型不一样图就不一样,这里的类型配的就是这里的图。
3.2 结合3.1的图,当x2的值小于x1时,我将x2的位置给了b,x1的位置给了x2(可以理解成x2和b都往前走了一步),这时三部分就变成两部分,x1没了???再用新区间再算一个(就用上面的公式,不要写错了),这时候又变成三部分了,我们可以看出现在比原来的范围小了。
3.3这时候假如x2的值>x1的值,同理a和x1往右走一步,a走到x1的位置,x1走到x2的位置,x2又没了??再用新区间算出x2
3.4就这样循环下去,你需要设置一个阈值,当b-a<?时就暂停,最终极值点的位置在(b-a)/2处 。
4.代码实现(区间ab我取的是2到8,分别写了x1的值>x2的值,x1的值<x2的值,x1的值==x2的值)
#include<iostream>
using namespace std;
int main()
{
//y=-x^2+10*x-15
float a = 2;
float b = 8;
float x1 = a + 0.382 * (b - a);
float x2 = a + 0.618 * (b - a);
float f1 = -x1 * x1 + 10 * x1 - 15;//赋值
float f2 = -x2 * x2 + 10 * x2 - 15;//赋值
int i = 1;
for (; i < 1000; i++)
{
if (f1 <f2)
{
a = x1;
x1 = x2;
f1 = f2;
x2 = a + 0.618 * (b - a);
f2 = -x2 * x2 + 10 * x2 - 15;
if (b - a < 0.001)
{
break;
}
}
if (f1 > f2)
{
b = x2;
x2 = x1;
f2 = f1;
x1= a + 0.382 * (b - a);
f1 = -x1 * x1 + 10 * x1 - 15;
if (b - a < 0.001)
{
break;
}
}
if (f1 == f2)
{
a = x1;
b = x2;
if (b - a < 0.001)
{
break;
}
if (b - a >= 0.001)
{
x1 = a + 0.382 * (b - a);
f1 = -x1 * x1 + 10 * x1 - 15;
x2 = a + 0.618 * (b - a);
f2 = -x2 * x2 + 10 * x2 - 15;
continue;
}
}
}
cout << "迭代次数:" << i << "次" << endl;
cout << "a的值为:" << a << " " << "b的值为:" << b << endl;
cout << "最终的位置是:" << (a + b) / 2 << endl;
}
5.结果
6.如果你要求单峰极小值(照着这个写)