Skip to content

第 7 章 中值定理与导数的应用 ​

学习目标 ​

  • 掌握罗尔定理与拉格朗日中值定理
  • 用一阶导数判断单调性与极值
  • 用二阶导数判断凹凸性与拐点
  • 会求闭区间上函数的最值
  • 掌握洛必达法则
  • 掌握泰勒公式,理解用多项式逼近函数

7.1 极值:山顶与谷底 ​

看函数 。它的图像先上升,在 处到达一个「山顶」,再下降,在 处到达一个「谷底」。

极大值(局部最大):若存在 附近的一个小区间,使得 是这个小区间里的最大值,则 叫极大值, 叫极大值点。极小值同理,只是把「最大」换成「最小」。

注意「局部」两个字:极大值只是「附近最高」,不一定是整个定义域最高。比如 在 处有极大值 2,但 也不比它小;而全局最高点要在闭区间上另找(7.5 节)。

费马引理:若 在 处可导,且 是极值点,则 。

证明(直觉版):如果 ,说明 右边函数在上升、左边在下降,那 左边有更大的值, 不可能是极大值点,也不可能是极小值点;如果 同理。只有 时,切线水平,才可能在「山顶」或「谷底」。注意这是必要条件: 的点(叫驻点)不一定是极值点,比如 在 处导数为 0,但函数单调递增,没有极值。

7.2 罗尔定理 ​

罗尔定理(Rolle's Theorem):若 在闭区间 上连续,在开区间 内可导,且 ,则存在 ,使得 。

直觉:从同一高度出发,走一段路又回到同一高度(比如先上坡后下坡),中间必然出现过水平的时候(山顶或谷底)。

证明思路:连续函数在闭区间上必有最大值 与最小值 (这是闭区间连续函数的性质,叫最值定理)。若 ,函数是常数,处处导数为 0;否则最大值或最小值至少有一个在区间内部取到,由费马引理,该点导数为 0。

7.3 拉格朗日中值定理 ​

拉格朗日中值定理(Mean Value Theorem):若 在 上连续、在 内可导,则存在 ,使得

直觉:从 走到 ,途中至少有一个时刻,瞬时速度等于全程平均速度。

证明:令

这是「曲线减去弦」:,。 满足罗尔定理条件,所以存在 使 。而

所以 ,即 。

验证: 在 上:

python
def f(x):
    return x ** 3 - 3 * x + 2

def fp(x):
    return 3 * x ** 2 - 3

a, b = -2.0, 2.0
k = (f(b) - f(a)) / (b - a)

lo, hi = 0.0, b
for _ in range(60):
    mid = (lo + hi) / 2
    if fp(mid) - k < 0:
        lo = mid
    else:
        hi = mid

print(f"f(a) = {f(a)}, f(b) = {f(b)}")
print(f"弦斜率 k = {k:.4f}")
print(f"c ≈ {mid:.4f},  f'(c) ≈ {fp(mid):.4f}")
text
f(a) = 0.0, f(b) = 4.0
弦斜率 k = 1.0000
c ≈ 1.1547,  f'(c) ≈ 1.0000

拉格朗日中值定理

python
import matplotlib.pyplot as plt
from matplotlib import font_manager
for f in font_manager.findSystemFonts():
    if any(k in f for k in ("NotoSansCJK", "NotoSansSC", "wqy", "SimHei", "msyh", "PingFang")):
        font_manager.fontManager.addfont(f)
plt.rcParams["font.sans-serif"] = ["Noto Sans CJK SC", "WenQuanYi Zen Hei", "SimHei", "Microsoft YaHei", "PingFang SC"]
plt.rcParams["axes.unicode_minus"] = False

import numpy as np

def f(x):
    return x ** 3 - 3 * x + 2

x = np.linspace(-2, 2, 400)
fig, ax = plt.subplots(figsize=(7, 5))
ax.plot(x, f(x), color="tab:blue", label="f(x) = x³ - 3x + 2")

a, b = -2.0, 2.0
ax.plot([a, b], [f(a), f(b)], color="tab:green", linestyle="--", label="弦")
c = 2 / np.sqrt(3)
xt = np.array([c - 0.6, c + 0.6])
ax.plot(xt, f(c) + 1.0 * (xt - c), color="tab:red", linewidth=2, label="切线(斜率 = 弦斜率)")
ax.scatter([c], [f(c)], color="tab:red", s=42, zorder=4)
ax.annotate(f"c ≈ {c:.4f}", (c, f(c)), textcoords="offset points", xytext=(8, 6), color="tab:red")

ax.set_xlim(-2.3, 2.3)
ax.set_ylim(-1.5, 5.5)
ax.axhline(0, color="black", linewidth=0.8)
ax.axvline(0, color="black", linewidth=0.8)
ax.grid(True, linestyle=":", alpha=0.5)
ax.legend(loc="upper left")
ax.set_title("中值定理:某点切线平行于弦")
fig.savefig("book/public/figs/fig07-mvt.png", dpi=120, bbox_inches="tight")
plt.close(fig)

7.4 单调性与极值判定 ​

中值定理的一个直接推论:若在区间 内 ,则 在该区间上单调递增;若 ,则单调递减。

为什么? 任取 ,由拉格朗日中值定理,。若 ,则差为正,所以 ,单调递增成立。

极值判定法(一阶导数法):若 在驻点 两侧变号:

  • 左正右负: 是极大值点;
  • 左负右正: 是极小值点;
  • 不变号: 不是极值点。

极值判定法(二阶导数法):若 且 ,则 是极小值点;若 ,则 是极大值点。

直觉:二阶导数 > 0 说明导数在上升,导数从负变正,函数先降后升,是谷底;二阶导数 < 0 则是山顶。

分析 :

驻点 。:,极大值;,极小值。

python
def fp(x):
    return 3 * x ** 2 - 3

for x0 in [-1.5, 0.0, 1.5]:
    print(f"x = {x0:5.1f}  f'(x) = {fp(x0):6.2f}")
text
x =  -1.5  f'(x) =   3.75
x =   0.0  f'(x) =  -3.00
x =   1.5  f'(x) =   3.75

导数为正 → 递增,为负 → 递减,符号变化一目了然。

7.5 凹凸性与拐点 ​

一阶导数描述「上升还是下降」,二阶导数描述「上升得越来越快还是越来越慢」,即曲线的凹凸。

  • :曲线凹向上(像碗,也叫凸函数 convex),切线在曲线下方;
  • :曲线凹向下(像倒扣的碗);
  • 且两侧变号:该点是拐点,曲线凹凸性改变。

单调性与凹凸

python
import matplotlib.pyplot as plt
from matplotlib import font_manager
for f in font_manager.findSystemFonts():
    if any(k in f for k in ("NotoSansCJK", "NotoSansSC", "wqy", "SimHei", "msyh", "PingFang")):
        font_manager.fontManager.addfont(f)
plt.rcParams["font.sans-serif"] = ["Noto Sans CJK SC", "WenQuanYi Zen Hei", "SimHei", "Microsoft YaHei", "PingFang SC"]
plt.rcParams["axes.unicode_minus"] = False

import numpy as np

x = np.linspace(-2.2, 2.2, 400)
fig, axes = plt.subplots(1, 2, figsize=(12, 4.6))

# 左:极值与单调性
axes[0].plot(x, x**3 - 3*x, color="tab:blue", label="f(x)")
axes[0].scatter([-1, 1], [2, -2], color="tab:red", s=40, zorder=4)
axes[0].annotate("极大值 2", (-1, 2), textcoords="offset points", xytext=(-42, 8), color="tab:red")
axes[0].annotate("极小值 -2", (1, -2), textcoords="offset points", xytext=(8, -18), color="tab:red")
axes[0].text(-1.6, 0.5, "递增", color="tab:green")
axes[0].text(0.15, -0.5, "递减", color="tab:orange")
axes[0].text(1.35, 0.5, "递增", color="tab:green")
axes[0].set_title("f(x) = x³ - 3x:极值与单调性")
axes[0].set_ylim(-4, 4)

# 右:凹凸
axes[1].plot(x, x**3 - 3*x, color="tab:blue", label="f(x)")
axes[1].plot(x, 6*x, color="tab:green", linestyle="--", label="f''(x) = 6x")
axes[1].axvline(0, color="tab:red", linestyle=":", linewidth=1.5)
axes[1].text(-2.0, 3.2, "f''<0 凹向下", color="tab:orange")
axes[1].text(0.35, 3.2, "f''>0 凹向上", color="tab:green")
axes[1].annotate("拐点", (0, 0), textcoords="offset points", xytext=(8, -18), color="tab:red")
axes[1].set_title("二阶导数与凹凸性")
axes[1].set_ylim(-4, 4)

for ax in axes:
    ax.axhline(0, color="black", linewidth=0.8)
    ax.axvline(0, color="black", linewidth=0.8)
    ax.grid(True, linestyle=":", alpha=0.5)
    ax.legend(fontsize=9)

fig.savefig("book/public/figs/fig07-extrema_concavity.png", dpi=120, bbox_inches="tight")
plt.close(fig)

7.6 闭区间上的最值 ​

求 在闭区间 上的最大值与最小值,只需比较两类候选点:

  1. 端点 、;
  2. 区间内 的驻点(以及不可导点,如果存在)。

为什么只需比较这些点? 最值定理保证最值存在;若最值在内部取到,它就是局部极值,由费马引理,该点导数为 0。

求 在 上的最值:

python
import numpy as np

def f(x):
    return x ** 3 - 3 * x

candidates = np.array([-2.0, -1.0, 1.0, 2.0])
values = f(candidates)
print("候选点:", candidates)
print("函数值:", values)
print("最大值:", values.max(), "出现在 x =", candidates[values.argmax()])
print("最小值:", values.min(), "出现在 x =", candidates[values.argmin()])
text
候选点: [-2. -1.  1.  2.]
函数值: [-2.  2. -2.  2.]
最大值: 2.0 出现在 x = -1.0
最小值: -2.0 出现在 x = -2.0

最大值 2 在 (局部极大)与 (端点)两处同时取到;最小值 同样在 与 两处取到。

7.7 洛必达法则 ​

处理 或 型极限,有一个强大的工具。

洛必达法则(L'Hôpital's Rule):若 (或都为 ),且 存在,则

直觉:两个函数在 附近都很小,谁更小取决于谁「下降得更快」,即导数的比值。比如 ,分子分母都趋于 0,导数之比 。

例子:。这是 型,求导一次后 仍是 ,再用一次:

python
import numpy as np

for x in [0.1, 0.01, 0.001]:
    print(f"x = {x:<6} (1-cos x)/x² = {(1 - np.cos(x)) / x**2:.8f}")
text
x = 0.1     (1-cos x)/x² = 0.49958347
x = 0.01    (1-cos x)/x² = 0.49999583
x = 0.001   (1-cos x)/x² = 0.49999996

7.8 泰勒公式:用多项式逼近 ​

多项式简单好算,而 、 等函数复杂。泰勒公式说:在点 附近,可导足够多次的函数可以用多项式任意精确地逼近。

泰勒公式:若 在 附近有直到 阶导数,则

其中 是余项,当 时比 更快趋于 0。前三项的道理很直白:多项式在 处的值、一阶导、二阶导……逐层与 匹配,逼近阶数越高越精确。

以 展开 。因为 的所有导数都是 ,,所以

在 处(即 ),逐项累加:

python
import math

x = 1.0
total = 0.0
for k in range(7):
    total += x ** k / math.factorial(k)
    print(f"n = {k}   T_{k}(1) = {total:.6f}")
print(f"e = {math.e:.6f}")
text
n = 0   T_0(1) = 1.000000
n = 1   T_1(1) = 2.000000
n = 2   T_2(1) = 2.500000
n = 3   T_3(1) = 2.666667
n = 4   T_4(1) = 2.708333
n = 5   T_5(1) = 2.716667
n = 6   T_6(1) = 2.718056
e = 2.718282

泰勒多项式逼近

python
import matplotlib.pyplot as plt
from matplotlib import font_manager
for f in font_manager.findSystemFonts():
    if any(k in f for k in ("NotoSansCJK", "NotoSansSC", "wqy", "SimHei", "msyh", "PingFang")):
        font_manager.fontManager.addfont(f)
plt.rcParams["font.sans-serif"] = ["Noto Sans CJK SC", "WenQuanYi Zen Hei", "SimHei", "Microsoft YaHei", "PingFang SC"]
plt.rcParams["axes.unicode_minus"] = False

import math
import numpy as np

x = np.linspace(-2.5, 2.5, 400)
fig, ax = plt.subplots(figsize=(7, 5))
ax.plot(x, np.exp(x), color="black", linewidth=2.2, label="e^x")

def taylor_n(x, n):
    total = np.zeros_like(x)
    for k in range(n + 1):
        total += x ** k / math.factorial(k)
    return total

for n, c in [(1, "tab:blue"), (2, "tab:green"), (3, "tab:orange"), (5, "tab:red")]:
    ax.plot(x, taylor_n(x, n), color=c, linestyle="--", label=f"T_{n}(x)")

ax.set_xlim(-2.5, 2.5)
ax.set_ylim(-1, 8)
ax.axhline(0, color="black", linewidth=0.8)
ax.axvline(0, color="black", linewidth=0.8)
ax.grid(True, linestyle=":", alpha=0.5)
ax.legend(loc="upper left", fontsize=9)
ax.set_title("e^x 的泰勒多项式:次数越高越接近")
fig.savefig("book/public/figs/fig07-taylor.png", dpi=120, bbox_inches="tight")
plt.close(fig)

7.9 动手实践:利润最大化 ​

某商品的利润 ( 为产量,单位百件)。求利润最大的产量。

二阶导数为负,所以 是极大值点,也是全局最大(二次函数开口向下,顶点即最大)。最大利润:

python
import numpy as np

def P(x):
    return -2 * x ** 2 + 120 * x - 1000

x = np.linspace(0, 60, 601)
i = np.argmax(P(x))
print(f"最大利润产量 ≈ x = {x[i]:.1f}")
print(f"最大利润 = {P(x[i]):.2f}")
text
最大利润产量 ≈ x = 30.0
最大利润 = 800.00

常见错误 ​

错误写法/理解原因
认为 必是极值点费马引理是必要条件;还要看二阶导数或两侧变号(反例: 在 0 处)
忘记比较端点闭区间最值可能在端点取到,只找驻点会漏答案
把局部极大值当成全局最大极大值是「附近最高」,全局最大要在整个定义域比较
洛必达法则直接用于非 、 型条件不满足时法则不适用
泰勒公式展开点搞错展开式每一项是 ,围绕 而非 0(除非 )

章末练习 ​

基础

  1. 求 的驻点,并判断每个驻点是极大值还是极小值。
  2. 求 在 上的最大值与最小值。
  3. 用洛必达法则求 。

提高

  1. 写出 在 处的前三项泰勒多项式,并用它估算 。
  2. 验证拉格朗日中值定理: 在 上,求满足定理的 。

挑战

  1. 证明:若 在区间上恒成立,则 是常数函数(用拉格朗日中值定理)。
  2. 某工厂成本 ,收益 。求利润 在 上的最大值点。

章末自测 ​

每题选择一个最佳答案。本书不附答案:完成后交由老师或 AI 老师批改讲解。

  1. 费马引理说的是:可导函数在极值点处,导数?
    • A. 不存在
    • B. 等于 0
    • C. 大于 0
    • D. 小于 0
  2. 罗尔定理额外要求 与 ?
    • A. 异号
    • B. 相等
    • C. 都大于 0
    • D. 无所谓
  3. 拉格朗日中值定理说:存在 ,使 等于?
    • A.
    • B.
    • C.
    • D. 0
  4. 若区间内 ,则 在该区间上?
    • A. 单调递减
    • B. 单调递增
    • C. 是常数
    • D. 凹凸不定
  5. 且 ,则 是?
    • A. 极大值点
    • B. 极小值点
    • C. 拐点
    • D. 端点
  6. 在 处?
    • A. 是极大值点
    • B. 是极小值点
    • C. 导数为 0 但不是极值点
    • D. 不可导
  7. 闭区间上连续函数的最值可能出现在?
    • A. 只有端点
    • B. 端点与驻点
    • C. 只有驻点
    • D. 任意点
  8. 等于?
    • A.
    • B.
    • C.
    • D. 不存在
  9. 在 处的二阶泰勒多项式是?
    • A.
    • B.
    • C.
    • D.
  10. 表示曲线?
    • A. 凹向上
    • B. 凹向下
    • C. 递增
    • D. 递减