抛物线法(二次插值法)

抛物线法简介

抛物线法(Quadratic Interpolation Method)是一种用于一维单峰函数极值搜索的经典优化方法。该方法通过在区间内选取三个不同的点,拟合一条二次抛物线,并求取这条抛物线的极值点作为新的迭代点,从而逐步逼近函数的极值。它相比于0.618法或黄金分割法,具有更快的收敛速度,特别是在极值点附近表现出超线性收敛特性。

数学推导

f ( x ) f(x) f(x) 在区间 内有单个极值点,选取不同的点 ( x 1 , f ( x 1 ) ) (x_1, f(x_1)) (x1,f(x1)) ( x 2 , f ( x 2 ) ) (x_2, f(x_2)) (x2,f(x2)) ( x 3 , f ( x 3 ) ) (x_3, f(x_3)) (x3,f(x3)), 用它们你和出一条二次抛物曲线

f ( x ) = A x 2 + B x + C f(x) = Ax^2 + Bx + C f(x)=Ax2+Bx+C
根据三点插值法,可以推导出抛物线极值点的公式

x m i n = f ( x 1 ) ( x 2 2 − x 3 2 ) + f ( x 2 ) ( x 3 2 − x 1 2 ) + f ( x 3 ) ( x 1 2 − x 2 2 ) 2 [ f ( x 1 ) ( x 2 − x 3 ) + f ( x 2 ) ( x 3 − x 1 ) + f ( x 3 ) ( x 1 − x 2 ) ] x_{min} = \frac{f(x_1) (x_2^2 -x_3^2) + f(x_2) (x_3^2 - x_1^2) + f(x_3)(x_1^2 -x_2^2)}{ 2[f(x_1)(x_2 - x_3) + f(x_2)(x_3 - x_1) + f(x_3)(x_1 - x_2)]} xmin=2[f(x1)(x2x3)+f(x2)(x3x1)+f(x3)(x1x2)]f(x1)(x22x32)+f(x2)(x32x12)+f(x3)(x12x22)
这个公式直接给出了二次曲线顶点的位置,作为当前迭代中的极小值近似。

算法流程

  • 选取初始区间 [ a , b ] [a, b] [a,b] 内的三个点 x 1 x_1 x1 x 2 x_2 x2 x 3 x_3 x3
    这三个点一般选取为 x 1 = a x_1 = a x1=a x 3 = b x_3 = b x3=b x 2 = a + b 2 x_2 = \frac{a+b}{2} x2=2a+b, 设定容许误差 η \eta η

  • 计算函数值 f ( x 1 ) f(x_1) f(x1) f ( x 2 ) f(x_2) f(x2) f ( x 3 ) f(x_3) f(x3)

  • 拟合抛物线,计算顶点 根据三点插值公式,拟合出二次函数,并计算顶点坐标:
    x m i n = f ( x 1 ) ( x 2 2 − x 3 2 ) + f ( x 2 ) ( x 3 2 − x 1 2 ) + f ( x 3 ) ( x 1 2 − x 2 2 ) 2 [ f ( x 1 ) ( x 2 − x 3 ) + f ( x 2 ) ( x 3 − x 1 ) + f ( x 3 ) ( x 1 − x 2 ) ] x_{min} = \frac{f(x_1) (x_2^2 -x_3^2) + f(x_2) (x_3^2 - x_1^2) + f(x_3)(x_1^2 -x_2^2)}{ 2[f(x_1)(x_2 - x_3) + f(x_2)(x_3 - x_1) + f(x_3)(x_1 - x_2)]} xmin=2[f(x1)(x2x3)+f(x2)(x3x1)+f(x3)(x1x2)]f(x1)(x22x32)+f(x2)(x32x12)+f(x3)(x12x22)

  • 判断是否满足精度要求 η \eta η
    如果
    ∣ x m i n − x 2 ∣ < η |x_{min} - x_2| < \eta xminx2<η
    说明收敛,极小值点为 x min x_{\text{min}} xmin,停止迭代。

  • 根据极值点位置和函数值更新三个点
    计算 f min = f ( x min ) f_{\text{min}} = f(x_{\text{min}}) fmin=f(xmin)
    比较 x min x_{\text{min}} xmin x 2 x_2 x2,分情况更新

情况条件更新方式
A x min < x 2 x_{\text{min}} < x_2 xmin<x2 f min < f 2 f_{\text{min}} < f_2 fmin<f2 x 3 ← x 2 x_3 \leftarrow x_2 x3x2, f 3 ← f 2 f_3 \leftarrow f_2 f3f2
x 2 ← x min x_2 \leftarrow x_{\text{min}} x2xmin, f 2 ← f min f_2 \leftarrow f_{\text{min}} f2fmin
B x min < x 2 x_{\text{min}} < x_2 xmin<x2 f min ≥ f 2 f_{\text{min}} \geq f_2 fminf2 x 1 ← x min x_1 \leftarrow x_{\text{min}} x1xmin, f 1 ← f min f_1 \leftarrow f_{\text{min}} f1fmin
C x min > x 2 x_{\text{min}} > x_2 xmin>x2 f min < f 2 f_{\text{min}} < f_2 fmin<f2 x 1 ← x 2 x_1 \leftarrow x_2 x1x2, f 1 ← f 2 f_1 \leftarrow f_2 f1f2
x 2 ← x min x_2 \leftarrow x_{\text{min}} x2xmin, f 2 ← f min f_2 \leftarrow f_{\text{min}} f2fmin
D x min > x 2 x_{\text{min}} > x_2 xmin>x2 f min ≥ f 2 f_{\text{min}} \geq f_2 fminf2 x 3 ← x min x_3 \leftarrow x_{\text{min}} x3xmin, f 3 ← f min f_3 \leftarrow f_{\text{min}} f3fmin
  1. 重复第 2 步到第 5 步, 直到收敛
    ∣ x min − x 2 ∣ < η |x_{\text{min}} - x_2| < \eta xminx2<η,返回 x min x_{\text{min}} xmin 作为极小值点

算法实现

#include <iostream>
#include <cmath>
#include <functional>
#include <algorithm>class QuadraticInterpolation {
private:double x1, x2, x3;                      // 三个采样点double eps;                             // 精度要求std::function<double(double)> func;     // 待优化目标函数public:// 构造函数QuadraticInterpolation(double a, double b, double e, std::function<double(double)> f): x1(a), x2((a + b) / 2), x3(b), eps(e), func(f) {}// 执行搜索double search() {double f1 = func(x1);double f2 = func(x2);double f3 = func(x3);double xmin;while (true) {// 抛物线拟合顶点公式double numerator = f1 * (std::pow(x2, 2) - std::pow(x3, 2)) +f2 * (std::pow(x3, 2) - std::pow(x1, 2)) +f3 * (std::pow(x1, 2) - std::pow(x2, 2));double denominator = 2 * (f1 * (x2 - x3) +f2 * (x3 - x1) +f3 * (x1 - x2));if (std::abs(denominator) < 1e-12) break; // 防止除0异常xmin = numerator / denominator;double fmin = func(xmin);// 判断是否达到精度if (std::fabs(xmin - x2) < eps) break;// 更新三点,保留较优的三个点if (xmin < x2) {if (fmin < f2) {x3 = x2;f3 = f2;x2 = xmin;f2 = fmin;}else {x1 = xmin;f1 = fmin;}}else {if (fmin < f2) {x1 = x2;f1 = f2;x2 = xmin;f2 = fmin;}else {x3 = xmin;f3 = fmin;}}}return xmin;}
};// 示例函数
double testFunc(double x) {return x * x - sin(x);
}int main() {// 构造优化器,区间[0,5],精度1e-6QuadraticInterpolation optimizer(0, 1, 1e-6, testFunc);double result = optimizer.search();std::cout << "极小值点 x ≈ " << result << std::endl;std::cout << "对应的 f(x) ≈ " << testFunc(result) << std::endl;return 0;
}

请添加图片描述

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation, PillowWriter# 定义目标函数
def f(x):return x**2 - np.sin(x)# 抛物线插值法计算顶点
def quadratic_interpolation(x1, x2, x3, f1, f2, f3):numerator = f1*(x2**2 - x3**2) + f2*(x3**2 - x1**2) + f3*(x1**2 - x2**2)denominator = 2*(f1*(x2 - x3) + f2*(x3 - x1) + f3*(x1 - x2))if np.abs(denominator) < 1e-12:return x2  # 防止除0return numerator / denominator# 初始参数
x1, x2, x3 = 0.0, 1.0, 2.0
eps = 1e-6# 函数取值范围
x_vals = np.linspace(0, 2.5, 400)
y_vals = f(x_vals)# 创建图形
fig, ax = plt.subplots(figsize=(8, 5))iteration = [0]  # 用 list 包一层,方便闭包修改def update(_):global x1, x2, x3iteration[0] += 1ax.clear()ax.plot(x_vals, y_vals, label="f(x) = $x^2 - \sin(x)$")f1, f2, f3 = f(x1), f(x2), f(x3)# 防止三点重合if abs(x1 - x2) < 1e-10 or abs(x1 - x3) < 1e-10 or abs(x2 - x3) < 1e-10:ani.event_source.stop()return# 拟合抛物线 y = A x^2 + B x + CX = np.array([[x1**2, x1, 1],[x2**2, x2, 1],[x3**2, x3, 1]])Y = np.array([f1, f2, f3])try:coeffs = np.linalg.solve(X, Y)except np.linalg.LinAlgError:ani.event_source.stop()returnA, B, C = coeffs# 拟合抛物线曲线x_fit = np.linspace(min(x1, x2, x3)-0.2, max(x1, x2, x3)+0.2, 200)y_fit = A * x_fit**2 + B * x_fit + Cax.plot(x_fit, y_fit, 'r--', label="Quadratic fit")# 计算拟合顶点xmin = quadratic_interpolation(x1, x2, x3, f1, f2, f3)fmin = f(xmin)# 绘制采样点和拟合点ax.plot([x1, x2, x3], [f1, f2, f3], 'go', label="Sample points")ax.plot(xmin, fmin, 'bo', label="New point")# 显示当前迭代信息ax.set_title(f"Iteration {iteration[0]}, x_min ≈ {xmin:.6f}")# 判断收敛,满足条件则停止动画if np.abs(xmin - x2) < eps:ani.event_source.stop()# 更新三点if xmin < x2:if fmin < f2:x3, f3 = x2, f2x2, f2 = xmin, fminelse:x1, f1 = xmin, fminelse:if fmin < f2:x1, f1 = x2, f2x2, f2 = xmin, fminelse:x3, f3 = xmin, fminax.legend()ax.set_xlim(0, 2.5)ax.set_ylim(-0.5, 5)ax.grid(True)# 动画:frames 不设定固定值,interval 控控制刷新速度
ani = FuncAnimation(fig, update, interval=500, repeat=False)# 保存 GIF
ani.save("quadratic_interpolation_auto_stop.gif", writer=PillowWriter(fps=2))plt.show()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/78965.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

FreeRTOS如何检测内存泄漏

在嵌入式系统中&#xff0c;内存资源通常非常有限&#xff0c;内存泄漏可能导致系统性能下降甚至崩溃。内存泄漏是指程序分配的内存未被正确释放&#xff0c;逐渐耗尽可用内存。 FreeRTOS作为一种轻量级实时操作系统&#xff08;RTOS&#xff09;&#xff0c;广泛应用于资源受限…

Mockoon 使用教程

文章目录 一、简介二、模拟接口1、Get2、Post 一、简介 1、Mockoon 可以快速模拟API&#xff0c;无需远程部署&#xff0c;无需帐户&#xff0c;免费&#xff0c;跨平台且开源&#xff0c;适合离线环境。 2、支持get、post、put、delete等所有格式。 二、模拟接口 1、Get 左…

如何进行APP安全加固

进行APP安全加固的关键在于代码混淆、加密敏感数据、权限管理、漏洞扫描与修复。其中&#xff0c;代码混淆能有效阻止逆向工程与篡改攻击&#xff0c;提升应用的安全防护能力。通过混淆代码&#xff0c;攻击者难以轻易理解源代码逻辑&#xff0c;从而降低被破解或攻击的风险。 …

【C++】手搓一个STL风格的string容器

C string类的解析式高效实现 GitHub地址 有梦想的电信狗 1. 引言&#xff1a;字符串处理的复杂性 ​ 在C标准库中&#xff0c;string类作为最常用的容器之一&#xff0c;其内部实现复杂度远超表面认知。本文将通过一个简易仿照STL的string类的完整实现&#xff0c;揭示其设…

辰鳗科技朱越洋:紧扣时代契机,全力投身能源转型战略赛道

国家能源局于4月28日出台的《关于促进能源领域民营经济发展若干举措的通知》&#xff08;以下简称《通知》&#xff09;&#xff0c;是继2月民营企业座谈会后深化能源领域市场化改革的关键政策&#xff0c;标志着民营经济在“双碳”目标引领下正式进入能源转型的核心赛道。 自…

Vue实现不同网站之间的Cookie共享功能

前言 最近有小伙伴在聊天室中提到这么一个需求&#xff0c;就是说希望用户在博客首页中登录了之后&#xff0c;可以跳转到管理系统去发布文章。这个需求的话就涉及到了不同网站之间cookie共享的功能&#xff0c;那么咱们就来试着解决一下这个功能。 实现方式 1. 后端做中转 …

在一台服务器上通过 Nginx 配置实现不同子域名访问静态文件和后端服务

一、域名解析配置 要实现通过不同子域名访问静态文件和后端服务&#xff0c;首先需要进行域名解析。在域名注册商或 DNS 服务商处&#xff0c;为你的两个子域名 blog.xxx.com 和 api.xxx.com 配置 A 记录或 CNAME 记录。将它们的 A 记录都指向你服务器的 IP 地址。例如&#x…

Opencv进阶操作:图像拼接

文章目录 前言一、图像拼接的原理1. 特征提取与匹配2. 图像配准3. 图像变换与投影4. 图像融合5. 优化与后处理 二、图像拼接的简单实现&#xff08;案例实现&#xff09;1.引入库2.定义cv_show()函数3.创建特征检测函数detectAndDescribe()4.读取拼接图片5.计算图片特征点及描述…

LLM 论文精读(三)Demystifying Long Chain-of-Thought Reasoning in LLMs

这是一篇2025年发表在arxiv中的LLM领域论文&#xff0c;主要描述了长思维链 Long Chain-of-Thought 对LLM的影响&#xff0c;以及其可能的生成机制。通过大量的消融实验证明了以下几点&#xff1a; 与shot CoT 相比&#xff0c;long CoT 的 SFT 可以扩展到更高的性能上限&…

计算机网络常识:缓存、长短连接 网络初探、URL、客户端与服务端、域名操作 tcp 三次握手 四次挥手

缓存&#xff1a; 缓存是对cpu&#xff0c;内存的一个节约&#xff1a;节约的是网络带宽资源 节约服务器的性能 资源的每次下载和请求都会造成服务器的一个压力 减少网络对资源拉取的延迟 这个就是浏览器缓存的一个好处 表示这个html页面的返回是不要缓存的 忽略缓存 需要每次…

《构建社交应用用户激励引擎:React Native与Flutter实战解析》

React Native凭借其与JavaScript和React的紧密联系&#xff0c;为开发者提供了一个熟悉且灵活的开发环境。在构建用户等级体系时&#xff0c;它能够充分利用现有的前端开发知识和工具。通过将用户在社交应用中的各种行为进行量化&#xff0c;比如发布动态的数量、点赞评论的次数…

接口自动化测试框架详解(pytest+allure+aiohttp+ 用例自动生成)

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 近期准备优先做接口测试的覆盖&#xff0c;为此需要开发一个测试框架&#xff0c;经过思考&#xff0c;这次依然想做点儿不一样的东西。 接口测试是比较讲究效…

Linux-----文件系统

文件大家都知道&#xff0c;前面的我的博客课程也为大家解释了关于文件的打开等&#xff0c;今天我们要谈论的是 文件在没被打开的时候在磁盘中的位置和找到它的方式。 画图为大家展示&#xff1a; 方便理解 我们从下面几个方面入手&#xff1a; 1. 看看物理磁盘 2. 了解一…

C++ set替换vector进行优化

文章目录 demo代码解释&#xff1a; 底层原理1. 二叉搜索树基础2. 红黑树的特性3. std::set 基于红黑树的实现优势4. 插入操作5. 删除操作6. 查找操作 demo #include <iostream> #include <set>int main() {// 创建一个存储整数的std::setstd::set<int> myS…

如何巧妙解决 Too many connections 报错?

1. 背景 在日常的 MySQL 运维中&#xff0c;难免会出现参数设置不合理&#xff0c;导致 MySQL 在使用过程中出现各种各样的问题。 今天&#xff0c;我们就来讲解一下 MySQL 运维中一种常见的问题&#xff1a;最大连接数设置不合理&#xff0c;一旦到了业务高峰期就会出现连接…

QT的布局和弹簧及其代码解读

this指的是真正的当前正在显示的窗口 main函数&#xff1a; Widget w是生成了一个主窗口&#xff0c;QT Designer是在这个主窗口里塞组件 w.show()用来展示这个主窗口 头文件&#xff1a; namespace Ui{class Widget;}中的class Widget和下面的class Widget不是一个东西 Ui…

《AI大模型应知应会100篇》第52篇:OpenAI API 使用指南与最佳实践

第52篇&#xff1a;OpenAI API 使用指南与最佳实践 &#x1f4cc; 摘要 本文将带你从零开始掌握 OpenAI API 的核心使用方法&#xff0c;涵盖从基础调用到高级功能的完整实战路径。通过详细的代码示例、图文解析和可运行的 Python 脚本&#xff0c;帮助你快速上手 GPT-3.5、GP…

C#学习7_面向对象:类、方法、修饰符

一、类 1class 1)定义类 访问修饰符class 类名{ 字段 构造函数&#xff1a;特殊的方法&#xff08;用于初始化对象&#xff09; 属性 方法... } eg: public class Person { // 字段 private string name; private int a…

湖北理元理律师事务所:债务优化中的“生活保障”方法论

债务危机往往伴随生活质量骤降&#xff0c;如何在还款与生存间找到平衡点&#xff0c;成为债务优化的核心挑战。湖北理元理律师事务所基于多年实务经验&#xff0c;提出“双轨并行”策略&#xff1a;法律减负与生活保障同步推进。 债务优化的“温度法则” 1.生存资金预留机制…

Jetpack Compose与Kotlin UI开发革命

Jetpack Compose + Kotlin:Android UI 开发的革命 简介 Jetpack Compose 是 Google 推出的现代 Android UI 工具包,结合 Kotlin 语言,彻底改变了传统 Android 开发的模式。过去,开发者依赖 XML 布局和命令式编程(如 findViewById 和手动更新视图),导致代码冗长且易出错…