0.618法
(黄金分割法)0.618法求极小点
给:f(x),范围[a,b],精度ε(无,则默认为0)
过程①
x1 = b - 0.618 * (b - a)。
x2 = a + 0.618 * (b - a)。
过程②
当f(x1) < f(x2)时, b = x2, a不变,再求x1,x2。
当f (x1) > f(x2)时, a = x1, b不变,再求x1,x2。
过程③
当|b - a| < ε时,最优解 x* = (b + a) / 2。
例:过程②
代码
import sympy
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
x=sympy.Symbol('x')
a=sympy.Symbol('a')
b=sympy.Symbol('b')
f=(x)**2-3*x+5
epsi=0.05
r=0.618
xb=b-r*(b-a)
xa=a+r*(b-a)
def accucy(a1,b1):
lx1 = []
ly1 = []
lx2 = []
ly2 = []
x1=xb.evalf(subs={b:b1,a:a1})
x2=xa.evalf(subs={b:b1,a:a1})
for i in range(1000): #主要的求解过程,默认为1000次循环,不可能无限循环
fx1=f.evalf(subs={x:x1})
fx2=f.evalf(subs={x:x2})
lx1.append(x1)
ly1.append(fx1)
lx2.append(x2)
ly2.append(fx2)
print(a1,b1)
if (b1-a1)<epsi:
print((b1+a1)/2)
break
if fx1>fx2:
a1=x1
x1=x2
x2=xa.evalf(subs={b:b1,a:a1})
else:
b1=x2
x2=x1
x1=xb.evalf(subs={b:b1,a:a1})
lx=lx1+lx2[:0:-1]
ly=ly1+ly2[:0:-1]
plt.plot(lx, ly, marker='o', color="red", label="0.168法")
def Graph():
ly=[]
lx=[]
for i in np.arange(1,2,0.05):
dk=f.evalf(subs={x:i})
ly.append(dk)
lx.append(i)
print(i,dk)
plt.plot(lx, ly, marker="o", color="blue",label="f函数")
accucy(1,2)
Graph()
plt.legend()
plt.show()