在构建复杂的 AI 模型或优化前端渲染性能时,我们经常需要回到数学的基础中去寻找答案。寻找函数的最大值和最小值不仅是微积分的入门课,更是现代算法优化、损失函数调整以及资源调度系统的核心逻辑。在这篇文章中,我们将不仅回顾经典的数学解法,还会结合 2026 年最新的“AI 原生”开发思维,探讨如何在现代工程中高效应用这些原理。
从基础出发:理解极值的本质
为了找到函数的最大值和最小值,我们需要求出给定函数的导数。如果对于所有 $x \in D$,都有 $f(x) \leq f(a)$,那么 $f(a)$ 就是该函数的最大值;反之,如果对于所有 $x \in D$,都有 $f(x) \geq f(a)$,那么 $f(a)$ 就是该函数的最小值。
经典数学解法:求函数最大值和最小值的步骤
虽然我们现在有 AI 辅助编程工具(如 Cursor 或 GitHub Copilot)可以帮我们快速生成代码,但理解底层逻辑依然是工程师的核心竞争力。让我们来总结求函数最大值和最小值的经典步骤,这在训练机器学习模型(如寻找梯度下降的最低点)时尤为重要:
- 步骤 1: 求出函数的一阶导数 $f‘(x)$。
- 步骤 2: 将函数的一阶导数设为 0,即 $f‘(x) = 0$。
- 步骤 3: 通过上述方程求出临界点。
- 步骤 4: 求出函数的二阶导数 $f‘‘(x)$。
- 步骤 5: 将临界点代入二阶导数中。如果结果值为负,则该点为极大值点;如果结果值为正,则该点为极小值点。
- 步骤 6: 将极大值点和极小值点代入原函数,我们就可以得到函数的最大值和最小值。
为了让大家更好地理解,我们将通过下面的例子进一步讲解:
例题:求函数 y = x3 – 3x + 11 的最大值和最小值
解法:
> y = x3 – 3x + 11
>
> 首先求一阶导数。对 y 进行求导
>
> y’ = (d / dx) [x3 – 3x + 11]
> ⇒ y’ = (d / dx) x3 – (d / dx) (3x) + (d / dx) 11
> ⇒ y’ = 3×2 – 3 + 0
> ⇒ y’ = 3×2 – 3
>
> 现在令 y’ = 0,来求临界点
>
> y’ = 0
> ⇒ 3×2 – 3 = 0
> ⇒ 3×2 = 3
> ⇒ x2 = 1
> ⇒ x = 1 或 x = -1
>
> 临界点为 x = 1 和 x = -1
>
> 现在我们要找二阶导数来检验这些临界点是极大值还是极小值。
>
> y” = (d / dx) [3×2 – 3]
> ⇒ y” = (d / dx) [3×2] – (d /dx) [3]
> ⇒ y” = 6x – 0
> ⇒ y” = 6x
>
> 现在我们要代入 x 的值,看看 y” 是大于 0 还是小于 0。
>
> 当 x = 1 时
>
> y” = 6(1) = 6
>
> 因为 y” > 0,所以 x = 1 是 y 的极小值点
>
> 当 x = -1 时
>
> y” = 6(-1) = -6
>
> 因为 y” < 0,所以 x = -1 是 y 的极大值点
>
> – y 在 x = -1 处取得最大值,(-1)3 -3(-1) + 11 = -1 + 3 + 11 = 13
> – y 在 x = 1 处取得最小值,(1)3 -3(1) + 11 = 1 – 3 + 11 = 9
进阶示例:生产环境中的极值计算
#### 例 1:求函数 f(x) = x3 + 8x2 + 16x + 2 的最大值和最小值
解法:
> f(x) = x3 + 8×2 + 16x + 2
>
> ⇒ f‘(x) = 3×2 + 16x + 16
>
> 然后,令 f‘(x) = 0,以寻找临界点。
>
> 3×2 + 16x + 16 = 0
> ⇒ 3×2 + 12x + 4x + 16 = 0
> ⇒ 3x (x + 4) + 4 (x + 4) = 0
> ⇒ (x + 4) (3x + 4) = 0
> ⇒ x = -4, -4/3
>
> 然后,求给定函数的 f‘‘(x)
>
> f‘‘(x) = 6x + 16
>
> 将临界点代入 f‘‘(x) 来确定最大值点和最小值点。
>
> 当 x = -4 时,f‘‘(x) = -8;当 x = -4/3 时,f‘‘(x) = 8
>
> 因为当 x = -4 时值为负,所以该点是最大值点;当 x = -4/3 时值为正,所以该点是最小值点。
>
> 然后,将这些值代入 f(x) 来求函数的最大值和最小值。
>
> – 最大值 = f(-4) = – 94
> – 最小值 = f(-4/3) = -202 /27 = -7.48
#### 例 2:求函数 g(x) = (x3 )/3 – (x2 )/2 – 6x +2 的最大值和最小值
解法:
> f(x) = (x3)/3 – (x2)/2 – 6x +2
> ⇒ f‘(x) = x2 – x – 6
>
> 然后,令 f‘(x) = 0,以寻找临界点。
>
> x2 – x – 6 = 0
> ⇒ x2 – 3x + 2x – 6 = 0
> ⇒ x (x – 3) + 2 (x – 3) = 0
> ⇒ (x + 2) (x – 3) = 0
> ⇒ x = -2, 3
>
> 然后,求给定函数的 f‘‘(x)
>
> f‘‘(x) = 2x – 1
>
> 将临界点代入 f‘‘(x) 来确定最大值点和最小值点。
>
> 当 x = -2 时,f‘‘(x) = -5;当 x = 3 时,f‘‘(x) = 5
>
> 因为当 x = -2 时值为负,所以该点是最大值点;当 x = 3 时值为正,所以该点是最小值点。
>
> 然后,将这些值代入 f(x) 来求函数的最大值和最小值。
>
> – 最大值 = f(-2) = 28/3
> – 最小值 = f(3) = -23/2
2026 工程视角:从数学公式到 Python 实现
在现代软件开发中,我们很少手动计算极值,而是编写代码让计算机去求解。特别是在数据科学和算法交易领域,这种自动化是至关重要的。
让我们看一个实际的例子。 假设我们正在为一个高频交易系统开发一个简单的损益分析工具,我们需要快速估算某个时间段内的最佳表现。
我们可以使用 Python 的 scipy.optimize 库,这在 2026 年已经是标配。但在使用工具之前,我们要明白“为什么”这样做。这就是Vibe Coding(氛围编程)的精髓:AI 负责写代码,我们负责理解意图和验证逻辑。
生产级代码示例:
import numpy as np
from scipy.optimize import minimize_scalar
import matplotlib.pyplot as plt
def objective_function(x):
"""
定义我们的目标函数 f(x) = x^2 - 4x + 1
这是一个典型的凸函数,存在全局最小值。
"""
return x**2 - 4*x + 1
# 我们使用 ‘Bounded‘ 方法来寻找特定区间内的极值
# 这模拟了我们在实际业务中受到资源或时间限制的场景
res = minimize_scalar(objective_function, bounds=(0, 10), method=‘bounded‘)
# 验证结果
if res.success:
print(f"找到最小值点: x = {res.x:.4f}")
print(f"最小函数值: f(x) = {res.fun:.4f}")
else:
print("优化失败:", res.message)
# 可视化展示(用于生成报告给非技术干系人)
x_values = np.linspace(0, 10, 100)
y_values = objective_function(x_values)
plt.figure(figsize=(8, 5))
plt.plot(x_values, y_values, label=‘f(x)‘)
plt.scatter(res.x, res.fun, color=‘red‘, zorder=5, label=‘Minimum‘)
plt.title(‘Function Optimization Analysis (2026 Project)‘)
plt.xlabel(‘Input Variable (x)‘)
plt.ylabel(‘Cost/Profit (y)‘)
plt.legend()
plt.grid(True)
# plt.show() # 在本地环境会显示图表,服务端环境通常保存为文件
代码解析与最佳实践:
- 函数定义的封装:我们总是将业务逻辑(数学公式)封装在独立的函数中。这不仅符合单一职责原则,也方便我们在 AI IDE 中使用 Agent 进行重构。
- 边界条件的处理:在 2026 年,随着计算资源向边缘计算迁移,我们不能无限制地消耗算力。通过
bounds参数限定搜索范围,能有效避免计算溢出,特别是在 Serverless 架构下控制成本。 - 可解释性:注意我们在代码中保留了详细的文档字符串。当 LLM 读取这段代码进行上下文理解时,这些注释能显著减少幻觉产生的错误代码。
深度解析:数值方法的局限性与陷阱
虽然上述 Python 方法很强大,但作为经验丰富的开发者,我们必须知道它可能在哪里“翻车”。在最近的几个项目中,我们遇到了一些由于忽视数学特性而导致的性能瓶颈。
#### 1. 局部极值 vs 全局极值
经典的导数法(以及基于梯度的优化算法)最容易陷入“局部最优解”。
想象一下,你的函数是一个崎岖的山脉,而不是一个平滑的碗。传统的梯度下降算法可能会在一个小山洼(局部最小值)停下来,以为到了平地,却没看到远处还有更深的峡谷(全局最小值)。
解决方案(2026 版):
我们现在倾向于使用启发式算法或多起点优化。例如,让 AI Agent 并行地(Agentic Workflow)从不同的随机起点开始寻找最小值,最后对比所有结果。
# 简单的多起点优化逻辑演示
results = []
for start_point in np.linspace(-10, 10, 20):
res = minimize(objective_function, start_point)
results.append(res.fun)
print(f"全局最小值候选: {min(results)}")
#### 2. 数值不稳定
当函数在极值点附近非常“平坦”时,计算机的浮点数精度误差可能会导致导数计算极其不稳定。在处理金融相关的极大极小值时,这 0.000001 的误差可能意味着巨额损失。
避坑指南: 在高精度要求场景下,尽量避免直接对离散数据进行数值求导,优先使用符号计算库如 SymPy,或者寻找该问题的解析解。
现代技术栈下的极值搜索:AI 驱动的未来
让我们把目光放得更长远一点。到了 2026 年,随着Agentic AI(自主智能体) 的普及,寻找极值的过程正在发生范式转移。
过去,我们是:
- 定义数学问题。
- 写代码求解。
- 调试代码。
现在(未来),我们在做 Vibe Coding:
- 告诉 AI Agent:“帮我分析这组过去 24 小时的系统日志数据,找到 CPU 负载的波峰和波谷,并预测下一次波峰。”
- Agent 自动编写代码(可能是 PyTorch,也可能是纯 SQL)。
- Agent 自动在沙盒环境中运行并验证结果。
- 我们只需审查 Agent 提供的报告。
在这种新范式下,理解“最大值/最小值”的概念依然重要,因为我们需要告诉 AI 我们的优化目标是什么——也就是定义损失函数或奖励函数。
实战场景:AI 辅助调试
你可能会遇到这样的情况:一个复杂的神经网络训练不收敛,Loss 值一直在震荡。这是一个寻找最小值失败的问题。
使用 2026 年的 AI IDE(如 Cursor),我们可以直接选中 Loss 变化曲线,向 AI 提问:“为什么我的模型无法找到 Loss 的最小值?”
AI 可能会回答:
> “你的学习率可能太大,导致函数在极值点附近来回跳跃。尝试使用 Adam 优化器,并引入学习率衰减策略。”
这本质上是在调整我们“下山”(寻找最小值)的步长策略。
总结与展望
无论是在数学课上求解 $y = x^3 – 3x + 11$,还是在构建下一代 Serverless 应用时优化云资源消耗,寻找最大值和最小值的逻辑始终贯穿其中。
在这篇文章中,我们回顾了经典的二阶导数测试法,展示了如何用 Python 实现自动化求解,并分享了 2026 年我们在面对高维、复杂函数时的工程化解决方案。希望这些内容能帮助你在未来的技术选型和架构设计中,做出更优的决策——毕竟,工程学的本质就是在约束条件下寻找最优解。
继续探索吧,下一次当你调试代码时,不妨想一想,你是否也在寻找属于你的那个“全局最小值”?
—-
#### 延伸阅读,