用黄金分割法(Golden Section Search Method)求函数最大值的python程序

一维搜索方法:一维搜索,又称一维优化,是指求解一维目标函数 f(X) 最优解的过程,分为试探法插值法。一维搜索最优化是优化方法中最简单、最基本的方法。
常用的方法有:等步长分割法黄金分割法(0.168法)牛顿法二次插值法

理论参考链接
一维搜索的最优方法(黄金分割法)

黄金分割法(Golden Section Search Method)

黄金分割法:属于一维搜索方法中的试探法。
#数学家华罗庚运用黄金分割法提出一种可以尽可能减少做试验次数、尽快地找到最优方案的方法——优选法
使用范围:适用于[a,b]区间上的任何单谷函数求极值问题。
思想:按照固定比例0.618取点,不断压缩极小点所在的区间,直到达到足够的精度水平。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
黄金分割的额来源:
在这里插入图片描述
在这里插入图片描述
算法搜索过程
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
黄金分割法计算框图:
在这里插入图片描述

例题

求函数A = 4*sinx *(1+cosx) 的最大值(x是角度)
x的范围是0~90°
收敛精度ε = 0.05
代码:

from sympy import *

a = 0  #区间下限
b = 90  #区间上限
dx = 0.05  #迭代精度

def func(x):
    A = 4*sin(x*pi.evalf()/180)*(1+cos(x*pi.evalf()/180))
    return A

i = 0
while True:
    i += 1
    x1 = b - 0.618*(b-a)
    x2 = a + 0.618*(b-a)
    if func(x1) > func(x2):
        b = x2
    elif func(x1) <= func(x2):
        a = x1
    DX = abs(b-a)
    if DX <= dx:
        print(f'迭代第{i}次,迭代精度小于等于{dx},最终的搜索区间为:{min(a, b), max(a, b)},A的最大值:{func((a + b) / 2)}')
        print('确定最大值的两端值为:', func(a), func(b))
        break
    else:
        pass

结果:

迭代第16,迭代精度小于等于0.05,最终的搜索区间为:(59.97388749678212, 60.01463097588722),A的最大值:5.19615237054102
确定最大值的两端值为: 5.19615134333327 5.19615208389224

黄金分割法迭代+绘图

仍然是上面的例子。
代码如下:

from sympy import *
import matplotlib.pyplot as plt

#函数
def func(x):
    A = 4*sin(x*pi.evalf()/180)*(1+cos(x*pi.evalf()/180))
    return A

#迭代过程
def iteration(a,b,dx):
    x_values = []
    x_values.append(a)
    x_values.append(b)
    i = 0
    while True:
        i += 1
        x1 = b - 0.618*(b-a)
        x2 = a + 0.618*(b-a)
        if func(x1) > func(x2):
            b = x2
            x_values.append(x2)
        elif func(x1) <= func(x2):
            a = x1
            x_values.append(x1)
        DX = abs(b-a)
        if DX <= dx:
            print(f'迭代第{i}次,迭代精度小于{dx},最终的搜索区间为:{min(a, b), max(a, b)},A的最大值:{func((a + b) / 2)}')
            print('确定最大值的两端值为:', func(a), func(b))
            break
        else:
            pass
    draw(x_values)

#绘图
def draw(x_values):
    #设置绘图风格
    plt.style.use('ggplot')
    #处理中文乱码
    plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
    #坐标轴负号的处理
    plt.rcParams['axes.unicode_minus']=False
    #横坐标是区间
    #纵坐标是函数值
    y_values = []
    x_values.sort()  #默认列表中的元素从小到大排列
    for x in x_values:
        y_values.append(func(x))
    #绘制折线图
    plt.plot(x_values,
             y_values,
             color = 'steelblue', # 折线颜色
             marker = 'o', # 折线图中添加圆点
             markersize = 3, # 点的大小
             )
    # 修改x轴和y轴标签
    plt.xlabel('区间')
    plt.ylabel('函数值')
    # 添加图形标题
    plt.title('Golden Section Search Method求函数最大值')
    # 显示图形
    plt.show()

if __name__ == '__main__':
    a = 0  # 区间下限
    b = 90  # 区间上限
    dx = 0.05  # 迭代精度
    iteration(a, b, dx)

结果:

迭代第16,迭代精度小于0.05,最终的搜索区间为:(59.97388749678212, 60.01463097588722),A的最大值:5.19615237054102
确定最大值的两端值为: 5.19615134333327 5.19615208389224

在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值