黄金分割法 ( 三分法 )

适用函数: 至少在搜索的初始区间内要是一个单峰函数

from sympy import *
import numpy as np
import math
import matplotlib.pyplot as plt


x,a,b,x1,x2 = symbols('x,a,b,x1,x2')
f1 = sin(x)
f2 = tan(1 - x)

# f  = -sin(x)**6 * tan(1 - x) * (math.e**30) ** x

f = math.e**x + math.e**(-x)

def get_value(t):
    return f.subs(x,t)


def golden_search(st,ed):
    a = st
    b = ed
    cnt = 1
    x1 =  a + 0.382*(b - a)
    x2 = a + 0.618*(b - a)
    print(cnt, ' ', a, " ", x1, ' ', x2, ' ', b)
    cnt += 1
    while b - a > 1e-10:
        x1_value = get_value(x1)
        x2_value = get_value(x2)
        if x1_value < x2_value:
            b = x2
            x2 = x1
            x1 = a + 0.382*(b - a)
        elif x1_value > x2_value:
            a = x1
            x1 = x2
            x2 = a + 0.618*(b - a)
        elif x1_value == x2_value:
            a = x1
            b = x2
            x1 = a + 0.382 * (b - a)
            x2 = a + 0.618 * (b - a)
        print(cnt,' ',a," ",x1,' ',x2,' ',b)
        cnt += 1
    ans = ( b + a )/ 2
    print('极小值点x*:', ans , '  极小值:' ,get_value(ans))




if __name__ == '__main__':
    st = -1  # 区间起始点
    ed = 2   # 区间终止点
    golden_search(st,ed)




    x1=np.arange(0,1.01,0.01)   # 注意右端点要去大一个dx!!!!!!
    # y1 = np.sin(x1)**6 * np.tan(1 - x1) * (np.e**30) ** x1
    # y1 = np.sin(x1)**6 * np.tan(1 - x1)* (math.e**(30*x1))
    y1 = ((np.e)**x1) + ((np.e)**(-1*x1))
    X,Y=np.meshgrid(x1,y1)
    plt.plot(x1,y1,"g-",lw=2.5,label="f(x)")
    # plt.title("e ^(x) + e ^ (-x)")
    plt.title("-sin(x1)^6 * tan(1 - x1) * e^(30*x1)")
    # plt.plot(step_x,step_y,c = 'r',marker = '*')
    plt.show()
发布了341 篇原创文章 · 获赞 32 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_41514525/article/details/103225232