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   #乘子: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) #a,b范围:[1,2]
Graph()
plt.legend()
plt.show()

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐