「最优化基础知识2」一维搜索,以及python代码

最优化基础知识(2)

无约束优化问题,一维搜索

一、一维搜索

一维搜索的意思是在一个方向上找到最小点。

用数学语言描述,X*=Xk +tPk,从Xk沿着Pk方向行走t到达最小点X*

1、收敛速度:
  1. 线性收敛:p=1,0<beta<1
  2. 超线性收敛: p>1或者beta=0
  3. 次线性收敛:p=1,beta=1
  4. p阶收敛:p>1
2、二次终止性:

能够在有限步内找到具有正定矩阵的二次函数的极小点。

f (X) = 1/2 XTAX + bTX + c

3、终止准则

什么时候停机,什么时候停止搜索。通常有以下五种:

1、黄金分割法

给定每次迭代区间缩小比例,如果做才能搜索次数最少?

黄金分割法的python代码:

python 复制代码
import math

def golden_section_search(f, a, b, tol=1e-6):
    golden_ratio = (math.sqrt(5) - 1) / 2
    length = b - a

    x1 = a + (1 - golden_ratio) * length
    x2 = a + golden_ratio * length

    while x2-x1>tol:
        print(x1,x2)
        if f(x1) < f(x2):
            b = x2
            x2 = x1
            x1 = a + (1 - golden_ratio) * (b - a)
        else:
            a = x1
            x1 = x2
            x2 = a + golden_ratio * (b - a)

    return (a + b) / 2

# 示例用法
def f(x):
    # 定义函数 f(x)
    return x*math.log(x)

# 在区间 [0, 5] 中寻找函数的极小值点
result = golden_section_search(f, 0, 5)
print(f"极小值点的位置为: {result}")
print(f"函数极小值为: {f(result)}")

2、fibonacci搜索

给定迭代次数,如何在迭代次数内达到最好的搜索效果(最后一次迭代完成,搜索区间最小)?

这个问题可以反过来理解,假设最后一次迭代完成,搜索区间长度为1,那么最开始的搜索区间最大为多少?

python代码:

python 复制代码
import math

def fibonacci_search(f, a, b, n):
    # 计算Fibonacci数列
    fibonacci = [0, 1]
    for i in range(n):
        fibonacci.append(fibonacci[-1] + fibonacci[-2])

    # 计算初始区间长度
    length = b - a

    # 计算初始比例
    ratio = (fibonacci[-3] / fibonacci[-1]) if len(fibonacci) > 2 else 0

    # 初始化区间端点
    x1 = a + ratio * length
    x2 = a + (1 - ratio) * length

    # 迭代搜索
    for _ in range(len(fibonacci) - 3):
        if f(x1) < f(x2):
            b = x2
            x2 = x1
            x1 = a + ratio * (b - a)
        else:
            a = x1
            x1 = x2
            x2 = a + (1 - ratio) * (b - a)
        fibonacci.pop()
        ratio = (fibonacci[-3] / fibonacci[-1])
        print(fibonacci[-3],fibonacci[-1],ration)
    # 返回最优解的位置
    return (a + b) / 2

# 示例用法
def f(x):
    # 定义函数 f(x)
    return x*math.log(x)

# 在区间 [-5, 5] 中寻找函数的极小值点
result = fibonacci_search(f, 0, 5, 30)
print(f"极小值点的位置为: {result}")
print(f"函数极小值为: {f(result)}")

在有的地方,直接给出的不是迭代次数,而是最终的区间长度的上界L,b1-a1是初始区间。
b n − a n = F n − 1 / F n ( b n − 1 − a n − 1 ) = F n − 1 F n F n − 2 F n − 1 ⋯ F 1 F 2 ( b 1 − a 1 ) b_n-a_n=F_{n-1}/F_{n}(b_{n-1}-a_{n-1}) = \frac{F_{n-1}}{F_{n}}\frac{F_{n-2}}{F_{n-1}}\cdots\frac{F_{1}}{F_{2}}(b_1-a_1) bn−an=Fn−1/Fn(bn−1−an−1)=FnFn−1Fn−1Fn−2⋯F2F1(b1−a1)

也就是说区间长度最小bn-an=(b1-a1)/F_n<=L,F_n是最大的fibonacci数。

关键:Fn-2+Fn-1=Fn,Fn-2/Fn+Fn-1/Fn=1,这样能保证每次删掉一侧的区间,比例是一样的。

当F6/F7=21/34=0.6176470588235294,和黄金分割法近似相同。

黄金分割法是fibonacci法的极限形式。

3、三点二次插值法

4、两点三次插值法

5、牛顿法

牛顿法就是在极小点附近选择一个初始点x0,在x0处二阶泰勒展开,并求其驻点。牛顿法不具有全局收敛性,因此初始点的选择很重要,它只是向初始点附近的驻点靠近。

牛顿法的python代码:

python 复制代码
import sympy as sp
def newton_method(f, x0, tol=1e-6, max_iter=100):
    f_d1 = f.diff()
    f_d2 = f_d1.diff()
    # 迭代搜索
    for _ in range(max_iter):
        # 计算导数值
        fx = f_d1.subs({x:x0})
        fxx = f_d2.subs({x:x0})

        # 更新搜索位置
        x1 = x0 - fx / fxx

        # 检查是否满足终止条件
        if abs(x1 - x0) < tol:
            break

        # 更新当前点
        x0 = x1

    # 返回搜索结果
    return x1

# 示例用法
x = sp.Symbol('x')
f=x**3-4*x+5

# 选择初始点
x0 = -10

# 使用牛顿法搜索函数的极小值点
result = newton_method(f, x0)
print(f"极小值点的位置为: {result.n()}")
print(f"函数极小值为: {f.subs({x:result}).n()}")

二、非精确一维搜索

1、Goldstein准则

2、Wolfe准则

3、Armijo准则

相关推荐
小白学大数据15 小时前
线上故障急救:依托 OpenClaw 日志排查 403 和 503 问题
爬虫·python·selenium·数据分析
databook15 小时前
用SymPy自动因式分解:从面积拼图到代数恒等式
python·数学·动效
艳阳天_.15 小时前
星瀚弹框页面实现
java·前端·python
kernelcraft16 小时前
Boto3:Python 操作 AWS 的官方 SDK
开发语言·python·其他·aws
D3bugRealm16 小时前
cryptography:Python 开发者的加密标准库
开发语言·python·其他
HappyAcmen16 小时前
5.通义向量模型调用
python
python-码博士17 小时前
PyTorch 从零实现 Flow Matching:训练、采样、画图一条龙
人工智能·pytorch·python
王小王-12317 小时前
基于Python的车联网数据聚合与可视化分析平台设计与实现
python·车联网·新能源汽车·车联网聚合分析
叫我:松哥17 小时前
基于Flask框架的校园二手书籍交易平台,注重校园场景的特殊需求,通过学号认证保障用户真实性
后端·python·sqlite·flask·bootstrap
namexingyun18 小时前
开源前端生态如何成为 AI UI 生成的“燃料“:shadcn/ui、Tailwind CSS、Storybook 技术价值全解剖
java·前端·人工智能·python·ui·开源·ai编程