用 Python 秒杀二元函数的极值问题

概念介绍

求解二元函数的极值需要使用偏导数和二阶导数的概念,我们先给出一般的求解步骤:

  1. 给定二元函数 f(x, y),计算它的一阶偏导数 ∂f/∂x 和 ∂f/∂y。
  2. 解方程组 ∂f/∂x = 0 和 ∂f/∂y = 0,求得临界点(或者称为驻点)。
  3. 计算二阶偏导数 ∂²f/∂x²,∂²f/∂y² 和 ∂²f/∂x∂y。
  4. 对于每个临界点,利用二阶偏导数判断其类型:
    • 如果 ∂²f/∂x² > 0 且 ∂²f/∂x²∂²f/∂y² - (∂²f/∂x∂y)² > 0,则该临界点为局部极小值点。
    • 如果 ∂²f/∂x² < 0 且 ∂²f/∂x²∂²f/∂y² - (∂²f/∂x∂y)² > 0,则该临界点为局部极大值点。
    • 如果 ∂²f/∂x²∂²f/∂y² - (∂²f/∂x∂y)² < 0,则该临界点为鞍点。
    • 如果 ∂²f/∂x²∂²f/∂y² - (∂²f/∂x∂y)² = 0,则二阶导数法无法确定其性质,需要使用其他方法进一步判断。
  5. 根据需要,可以进一步将临界点带入函数 f(x, y) 计算出对应的函数值。

求解程序

下面给出 Python 代码,我们这里测试的函数是

f(x,y) = (y-x^2)*(y-x^3)

import sympy as sp
import numpy as np

# 定义变量
x, y = sp.symbols('x y')

# 定义二元函数
f = (y-x**2)*(y-x**3)

# 计算一阶偏导数
df_dx = sp.diff(f, x)
df_dy = sp.diff(f, y)

# 解方程组
critical_points = sp.solve((df_dx, df_dy), (x, y))

# 计算二阶偏导数
d2f_dx2 = sp.diff(df_dx, x)
d2f_dy2 = sp.diff(df_dy, y)
d2f_dxdy = sp.diff(df_dx, y)

# 判断临界点类型并输出结果
for point in critical_points:
    x_val, y_val = point
    d2f_dx2_val = d2f_dx2.subs([(x, x_val), (y, y_val)]).evalf()
    d2f_dy2_val = d2f_dy2.subs([(x, x_val), (y, y_val)]).evalf()
    d2f_dxdy_val = d2f_dxdy.subs([(x, x_val), (y, y_val)]).evalf()

    discriminant = d2f_dx2_val * d2f_dy2_val - d2f_dxdy_val**2

    if discriminant > 0 and d2f_dx2_val > 0:
        print(f"局部极小值点:({x_val}, {y_val})")
    elif discriminant > 0 and d2f_dx2_val < 0:
        print(f"局部极大值点:({x_val}, {y_val})")
    elif discriminant < 0:
        print(f"鞍点:({x_val}, {y_val})")
    else:
        print(f"二阶导数法无法确定临界点:({x_val}, {y_val})")

这段代码涉及到了符号计算和数值计算,主要是对二元函数进行求导和求临界点类型的判断。

首先,代码导入了`sympy`(用于符号计算)和`numpy`(用于数值计算)两个库。然后,定义了两个符号变量`x`和`y`,代表函数中的自变量。

接下来,定义了一个二元函数`f`,表示 `(y-x**2)*(y-x**3)`。这个函数是一个关于 `x` 和 `y` 的二次方程。

然后,使用`sympy`中的`diff`函数分别计算了函数`f`对于`x`和`y`的一阶偏导数,分别存储在变量`df_dx`和`df_dy`中。

通过调用`sympy`中的`solve`函数,解决了一组方程组,即求解 `(df_dx, df_dy) = 0` 所对应的 `(x, y)` 的值,并将结果存储在`critical_points`中。

然后,分别计算了二阶偏导数 `d2f_dx2`、`d2f_dy2` 和 `d2f_dxdy`。

接下来,通过遍历`critical_points`列表中的临界点,逐个计算二阶偏导数的值,并根据判别式的结果,判断临界点的类型。

- 如果判别式大于0且二阶偏导数 `d2f_dx2_val` 大于0,则该临界点为局部极小值点。
- 如果判别式大于0且二阶偏导数 `d2f_dx2_val` 小于0,则该临界点为局部极大值点。
- 如果判别式小于0,则该临界点是一个鞍点(saddle point)。
- 如果判别式无法确定临界点类型,则输出无法确定。

最后,根据判断结果输出相应的信息。

总结起来,这段代码通过符号计算和数值计算的方式,求解了二元函数的一阶偏导数、二阶偏导数,并根据判别式判断了临界点的类型。

运行结果如下: 

注意,鞍点不是极值点。

实际应用

如上图所示,一个长方体盒子六个面的面积和固定为12平方米,求出最大的体积。

我们设盒子长宽高为x,y,z,体积为V。其中V可以表示为

V=xyz

面积方程为

2xy+2xz+2yz=12

得出

z=\frac{12-xy}{2(x+y)}

V=xy\frac{(12-xy)}{(2(x+y))}

我们直接代入程序

# 定义二元函数
f = x*y*(12-x*y)/(2*(x+y))

结果如下

也就是当 x=2,y=2,z=(12-2*2)/(2*(2+2)) = 1取得极大值

即我们最大的体积为2*2*1=4立方米。

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

热爱技术的小胡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值