简介
0.618法(Golden Section Search)又称黄金分割法,是一种用于一维函数优化的方法。该方法基于黄金分割点的概念,通过不断缩小搜索范围来逼近函数的最优解。
具体步骤如下:
- 选取一个初始区间[a, b],确保函数在该区间内是凸函数。
- 计算两个内分点c和d,使得c = a + 0.382(b - a),d =a + 0.618(b - a)。
- 比较在c和d处的函数值,确定新的区间[a, b]。
- 不断重复步骤2和步骤3,直到满足收敛条件为止。
0.618法的优点是收敛速度比较快,且不需要函数的导数信息。然而,该方法对初始区间的选取比较敏感,可能会导致结果受到区间选择的影响。
优化问题
求解 m i n ϕ ( x ) = x 2 + 2 x min\phi(x)=x^{2}+2x minϕ(x)=x2+2x, s . t . − 3 ≤ x ≤ 5 s.t. -3\le x\le 5 s.t.−3≤x≤5,明显 ϕ ( x ) \phi(x) ϕ(x)在可行域区间上是凸函数,因此,设置收敛精度 δ = 1 e − 3 \delta=1e^{-3} δ=1e−3。计算程序如下:
# 采用0.618法求解凸函数的极小值
def golden_section_method(a, b, gap):
"""
采用黄金分分割法求解f(x)=x**2+2*x,在区间[-3,5]上的最小值
:param a: 区间左端点
:param b: 区间右端点
:param gap: 收敛精度
"""
i = 0
while (b-a) > gap:
x1 = a+0.382*(b-a)
x2 = a+0.618*(b-a)
f_x1 = cal_fun_value(x1)
f_x2 = cal_fun_value(x2)
if f_x1 < f_x2:
a = a
b = x2
else:
a = x1
b = b
i += 1
print(f"第{i}次迭代最小值", (a+b)/2)
# 计算函数值
def cal_fun_value(x):
return x**2+2*x
if __name__ == "__main__":
golden_section_method(-3, 5, 1e-3)
结果输出如下:
第1次迭代最小值 -0.528
第2次迭代最小值 -1.472304
第3次迭代最小值 -0.8887241280000001
第4次迭代最小值 -1.2493764888960002
第5次迭代最小值 -1.026493329862272
第6次迭代最小值 -0.8887515375794283
第7次迭代最小值 -0.9738759652102258
第8次迭代最小值 -1.0264828614860586
第9次迭代最小值 -0.9939717995875939
第10次迭代最小值 -1.014063635840845
第11次迭代最小值 -1.001646881036336
第12次迭代最小值 -0.9939733265671491
第13次迭代最小值 -0.9987155832291066
第14次迭代最小值 -1.0016462978461962
第15次迭代最小值 -0.9998351162128348
第16次迭代最小值 -1.0009544264622523
第17次迭代最小值 -1.0002626927281124
第18次迭代最小值 -0.9998352012804138
第19次迭代最小值 -1.0000993909950915
可知当计算到第19次时已经满足收敛精度了得到极小值点为-1。