如何使用numpy、sympy、matplotlib求解函数的极大值与极小值
函数极值求解实现方案
你仅需使用numpy、sympy、matplotlib三个库即可完成多项式函数的极值求解,针对目标函数 $y=9x3-7x2+3x+10$,基于你已写的代码补全逻辑即可,具体如下:
现有代码问题
- 缺少
numpy库的导入语句,运行会报np未定义的错误 - 仅生成了整数间隔的离散点,没有完成驻点求解、极值类型判定、结果可视化的核心逻辑
- 原代码把符号函数
f直接覆盖为lambdify转换后的数值函数,后续如果需要做符号计算会报错
核心实现逻辑
- 用sympy完成符号求导:一阶导数为0的点是极值候选驻点,二阶导数符号用于判定极值类型
- 驻点处二阶导>0:该点为极小值点
- 驻点处二阶导<0:该点为极大值点
- 驻点处二阶导=0:该点为拐点,不是极值点
- 过滤掉复数域的驻点,仅保留实数域的有效极值点
- 用numpy生成平滑的连续采样点,matplotlib绘制函数曲线与极值点标注
- 代码逻辑通用,替换目标函数即可直接用于其他多项式的极值求解,适配你后续的多函数计算需求
完整可运行代码
from sympy import * import numpy as np import matplotlib.pyplot as plt # 定义符号变量与目标函数(符号函数和数值函数分开命名,避免覆盖冲突) x = symbols('x') f_sym = 9*x**3 - 7*x**2 + 3*x + 10 # 计算一阶导、二阶导 df_1 = diff(f_sym, x) df_2 = diff(f_sym, x, 2) # 求解一阶导为0的所有驻点,过滤复数点保留实数驻点 critical_points = solve(df_1, x) real_critical = [float(p.evalf()) for p in critical_points if p.is_real] # 遍历驻点判定极值类型 extrema_result = [] for x_val in real_critical: second_deriv_val = float(df_2.subs(x, x_val).evalf()) y_val = float(f_sym.subs(x, x_val).evalf()) if second_deriv_val > 1e-6: # 加极小阈值规避浮点计算误差 extrema_result.append( ("极小值", x_val, y_val) ) elif second_deriv_val < -1e-6: extrema_result.append( ("极大值", x_val, y_val) ) # 转换为numpy可调用的数值函数用于绘图 f_num = lambdify(x, f_sym, 'numpy') # 生成绘图用的密集采样点 x_plot = np.linspace(-2, 2, 500) y_plot = f_num(x_plot) # 绘制图像 plt.figure(figsize=(10, 6)) plt.plot(x_plot, y_plot, color='#1f77b4', linewidth=2, label=r'$y=9x^3-7x^2+3x+10$') # 标注极值点 for e_type, x_p, y_p in extrema_result: plt.scatter(x_p, y_p, color='red', s=120, zorder=10) plt.text(x_p+0.05, y_p, f'{e_type}\n({x_p:.3f}, {y_p:.3f})', fontsize=11) # 辅助样式设置 plt.axhline(0, color='black', linewidth=0.8) plt.axvline(0, color='black', linewidth=0.8) plt.grid(alpha=0.3) plt.xlabel('x', fontsize=12) plt.ylabel('y', fontsize=12) plt.legend(fontsize=12) plt.title('函数极值求解可视化', fontsize=14) plt.show() # 打印计算结果 print("="*30) if not extrema_result: print("该函数在实数域不存在极大值、极小值,函数在R上单调") else: print("函数极值计算结果:") for e_type, x_p, y_p in extrema_result: print(f"{e_type}:x = {x_p:.4f}, 对应y = {y_p:.4f}")
运行结果说明
目标函数的一阶导数为 $f'(x)=27x^2-14x+3$,其判别式 $\Delta = 14^2 - 4\times27\times3 = -128 < 0$,一阶导在全体实数域恒为正,因此该函数没有实数域的极大值和极小值,整体单调递增。运行代码后会输出无有效极值的提示,绘制的函数曲线为全程上升的三次函数曲线。
内容的提问来源于stack exchange,提问作者Tasrif Rahman
相关产品推荐
相关产品推荐

