You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

SymPy中使用nonlinsolve求解非线性方程组未得到正确数值解的解决方案咨询

获取nonlinsolve的非线性方程组数值解

你遇到的问题是因为nonlinsolve默认返回参数化的符号解集,而solve在能推导出唯一数值解时会直接给出结果。要通过nonlinsolve拿到正确的数值解,有两种可行的思路:


方法1:从参数化解集提取并求解具体值

nonlinsolve返回的{(-4*y/5 + 4, y)}是用y表示x的参数化解集,我们可以将这个表达式代入原方程组,求解出y的具体值后反推x:

from sympy import *
x, y = symbols('x, y')
eq1 = Eq(diff(8*x**0.5*y**0.5, x)/10, diff(8*x**0.5*y**0.5, y)/8)
eq2 = Eq(40, 10*x + 8*y)

# 获取nonlinsolve的参数化解集
sol_set = nonlinsolve([eq1, eq2], [x, y])
# 取出解集中的元组(x的表达式,y)
x_expr, _ = next(iter(sol_set))

# 将x的表达式代入eq1,得到关于y的方程
y_eq = eq1.subs(x, x_expr)
# 求解y的符号解
y_sol = solve(y_eq, y)[0]
# 代入得到x的符号解
x_sol = x_expr.subs(y, y_sol)

# 转换为数值解
print(f"x: {x_sol.evalf()}, y: {y_sol.evalf()}")

运行后会输出:

x: 2.00000000000000, y: 2.50000000000000

方法2:先化简方程组再调用nonlinsolve

原方程eq1求导后可以进一步化简,直接用化简后的方程组调用nonlinsolve,就能直接得到符号形式的精确解,再转换为数值解:

from sympy import *
x, y = symbols('x, y')
eq1 = Eq(diff(8*x**0.5*y**0.5, x)/10, diff(8*x**0.5*y**0.5, y)/8)
eq2 = Eq(40, 10*x + 8*y)

# 化简eq1,得到4y=5x的等价形式
simplified_eq1 = simplify(eq1)

# 用化简后的方程组求解
sol_set = nonlinsolve([simplified_eq1, eq2], [x, y])
x_sol, y_sol = next(iter(sol_set))

# 转换为数值解
print(f"x: {x_sol.evalf()}, y: {y_sol.evalf()}")

运行后同样会得到正确的数值解,而且这个方法更高效——化简后的方程组结构更清晰,nonlinsolve能直接推导出唯一解。


为什么会有差异?

solve内部会自动尝试多种化简和求解策略,在遇到有唯一数值解的方程组时,会直接返回数值结果;而nonlinsolve更侧重符号解集的完整性,默认返回参数化形式(即使存在唯一解),需要我们手动进一步处理或提前化简方程组来得到具体数值。

内容的提问来源于stack exchange,提问作者Masa_K

火山引擎 最新活动