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

等步长分割法(Equal Interval Search Method)

等步长分割法属于试探法,其原理跟二分法一样。

迭代过程中压缩比例不变,只使用目标函数值f(x)。

适用范围:黄金分割法适用于[a,b]区间上任何单谷函数求极小值(存在唯一的局部极小点)问题。

思想:按照固定比例0.5取点,不断压缩极值点所在的区间,直到达到足够的精度水平。

python 求tensor最大值 索引_等间距分割法求最大值


python 求tensor最大值 索引_搜索_02


python 求tensor最大值 索引_python_03


Chapter 09.01 Golden Section Search Method算法搜索过程

1、给出初始搜索区间[a,b],以及收敛精度ε;

2、按照公式计算下一个迭代点及函数值;

3、根据函数值确定压缩后的新区间;

4、检查新区间是否满足收敛精度b-a<=ε。

计算迭代点公式:

x1 = (a+b)/2 - ε/2

x2 = (a+b)/2 + ε/2

如果 f(x1) > f(x2) —— 搜索区间变为[a,x2] (这里函数求最大值)

如果 f(x1) < f(x2) —— 搜索区间变为[x1,b] (这里函数求最大值)

直到第一次和第二次两端值的误差在所约定的范围内时,求得最大值

此时搜索区间为[A,B],那么函数最大值为f((A+B)/2)

例题:

求函数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 = (a + b) / 2 - dx / 2
    x2 = (a + b) / 2 + dx / 2
    if func(x1) > func(x2):
        b = x2
    elif func(x1) <= func(x2):
        a = x1
    DX = round(abs(b - a),3)  #(b-a)是不可能小于0.05的,所以让其近似于0.050即可。round()函数是保留小数点以后几位数
    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

结果:

迭代第18次,迭代精度小于等于0.05,最终的搜索区间为:(59.97467308044435, 60.02501621246339),A的最大值:5.19615242266843
确定最大值的两端值为: 5.19615140730401 5.19615143223232

等步长分割法迭代+绘图

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

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 = (a + b) / 2 - dx / 2
        x2 = (a + b) / 2 + dx / 2
        if func(x1) > func(x2):
            b = x2
            x_values.append(x2)
        elif func(x1) <= func(x2):
            a = x1
            x_values.append(x1)
        DX = round(abs(b - a),3)  #(b-a)是不可能小于0.05的,所以让其近似于0.050即可
        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('Equal Interval Search Method求函数最大值')
    # 显示图形
    plt.show()

if __name__ == '__main__':
    a = 0  # 初始下区间
    b = 90  # 初始上区间
    dx = 0.05  # 收敛精度
    iteration(a,b,dx)

结果:

迭代第18次,迭代精度小于0.05,最终的搜索区间为:(59.97467308044435, 60.02501621246339),A的最大值:5.19615242266843
确定最大值的两端值为: 5.19615140730401 5.19615143223232

python 求tensor最大值 索引_算法_04