You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何指定SymPy中的已知变量?求解线性方程组获空解求助

问题描述

我正尝试使用SymPy求解一个包含32个未知变量、4个已知变量(e, j, o, t)和34个方程的大型方程组,目标是得到仅依赖已知变量的u, v, w, y, z, c_c的表达式,但不知道如何告知SymPye, j, o, t是已知变量。运行代码后输出空列表[],代码如下:

import sympy as sp

a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z = sp.symbols(
    'a b c d e f g h i j k l m n o p q r s t u v w x y z')
a_a, b_b, c_c, e_e, t_t, f_f, m_m, p_p, s_s, o_o = sp.symbols(
    'a_a b_b c_c e_e t_t f_f m_m p_p s_s o_o')

eq1 = sp.Eq(a+b+c+d, e)
eq2 = sp.Eq(f+g+h+i, j)
eq3 = sp.Eq(k+l+m+n, o)
eq4 = sp.Eq(p+q+r+s, t)
eq5 = sp.Eq(a+f+k+p, 1)
eq6 = sp.Eq(b+g+l+q, 1)
eq7 = sp.Eq(c+h+m+r, 1)
eq8 = sp.Eq(d+i+n+s, 1)
eq9 = sp.Eq(1/m_m, a)
eq10 = sp.Eq(x/m_m, f)
eq11 = sp.Eq(a_a/m_m, k)
eq12 = sp.Eq(e_e/m_m, p)
eq13 = sp.Eq(u/p_p, b)
eq14 = sp.Eq(1/p_p, g)
eq15 = sp.Eq(b_b/p_p, l)
eq16 = sp.Eq(t_t/p_p, q)
eq17 = sp.Eq(v/s_s, l)
eq18 = sp.Eq(y/s_s, h)
eq19 = sp.Eq(1/s_s, m)
eq20 = sp.Eq(f_f/s_s, r)
eq21 = sp.Eq(w/o_o, d)
eq22 = sp.Eq(z/o_o, i)
eq23 = sp.Eq(c_c/o_o, n)
eq24 = sp.Eq(1/o_o, s)
eq25 = sp.Eq(x, 1/u)
eq26 = sp.Eq(a_a, 1/v)
eq27 = sp.Eq(e_e, 1/w)
eq28 = sp.Eq(b_b, 1/y)
eq29 = sp.Eq(t_t, 1/z)
eq30 = sp.Eq(f_f, 1/c_c)
eq31 = sp.Eq(1+x+a_a+e_e, m_m)
eq32 = sp.Eq(u+1+b_b+t_t, p_p)
eq33 = sp.Eq(v+y+1+f_f, s_s)
eq34 = sp.Eq(w+z+c_c+1, o_o)

solution = sp.solve((eq1, eq2, eq3, eq4, eq5, eq6,
                    eq7, eq8, eq9, eq10, eq11, eq12,
                    eq13, eq14, eq15, eq16, eq17, eq18,
                    eq19, eq20, eq21, eq22, eq23, eq24,
                    eq25, eq26, eq27, eq28, eq29, eq30,
                    eq31, eq32, eq33, eq34
                     ), u, v, w, y, z, c_c)

print(solution)
解决方案

1. 明确已知变量的处理方式

SymPy的solve函数不需要专门标记已知变量,只需明确指定要解出的未知变量列表,其余未被指定的符号会自动被当作已知常量处理。

2. 分步简化方程组

原方程组嵌套了大量代换关系,直接一次性求解会增加SymPy的推导难度,建议先将中间变量用目标变量代换,再代入核心方程求解:

修改后的代码示例:

import sympy as sp

# 定义所有符号
a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z = sp.symbols(
    'a b c d e f g h i j k l m n o p q r s t u v w x y z')
a_a, b_b, c_c, e_e, t_t, f_f, m_m, p_p, s_s, o_o = sp.symbols(
    'a_a b_b c_c e_e t_t f_f m_m p_p s_s o_o')

# 先处理代换关系,将中间变量用目标变量表示
subs_map = {
    x: 1/u,
    a_a: 1/v,
    e_e: 1/w,
    b_b: 1/y,
    t_t: 1/z,
    f_f: 1/c_c,
    m_m: 1 + x + a_a + e_e,
    p_p: u + 1 + b_b + t_t,
    s_s: v + y + 1 + f_f,
    o_o: w + z + c_c + 1,
    a: 1/m_m,
    f: x/m_m,
    k: a_a/m_m,
    p: e_e/m_m,
    b: u/p_p,
    g: 1/p_p,
    l: b_b/p_p,
    q: t_t/p_p,
    h: y/s_s,
    m: 1/s_s,
    r: f_f/s_s,
    d: w/o_o,
    i: z/o_o,
    n: c_c/o_o,
    s: 1/o_o
}

# 补充l的约束:原eq15和eq17都定义了l,需将其加入方程组
eq_l_constraint = sp.Eq(b_b/p_p, v/s_s).subs(subs_map)

# 将代换代入核心方程(eq1到eq8)
core_eqs = [
    sp.Eq(a+b+c+d, e).subs(subs_map),
    sp.Eq(f+g+h+i, j).subs(subs_map),
    sp.Eq(k+l+m+n, o).subs(subs_map),
    sp.Eq(p+q+r+s, t).subs(subs_map),
    sp.Eq(a+f+k+p, 1).subs(subs_map),
    sp.Eq(b+g+l+q, 1).subs(subs_map),
    sp.Eq(c+h+m+r, 1).subs(subs_map),
    sp.Eq(d+i+n+s, 1).subs(subs_map),
    eq_l_constraint
]

# 求解目标变量,e,j,o,t自动作为已知量
solution = sp.solve(core_eqs, (u, v, w, y, z, c_c), dict=True)

# 输出结果
for idx, sol in enumerate(solution):
    print(f"解 {idx+1}:")
    print(f"u = {sp.simplify(sol[u])}")
    print(f"v = {sp.simplify(sol[v])}")
    print(f"w = {sp.simplify(sol[w])}")
    print(f"y = {sp.simplify(sol[y])}")
    print(f"z = {sp.simplify(sol[z])}")
    print(f"c_c = {sp.simplify(sol[c_c])}")
    print("---")

3. 关键注意事项

  • 原方程组中eq15和eq17都定义了变量l,这两个表达式必须等价,否则方程组无解,需将其作为约束方程加入求解列表。
  • 分步代换能降低计算复杂度,避免SymPy因处理超大型方程组出现推导停滞或返回空解的情况。
  • 调用solve时,传入目标变量元组(u, v, w, y, z, c_c),SymPy会自动将e,j,o,t等未指定符号视为已知常量。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 06:25:50