本文介绍如何使用 sympy 符号求解器准确求解包含四个未知复数节点电压(v₁, v₂, v₃, vₙ)的耦合代数方程组,并提取可用于后续数值计算的浮点结果。
本文介绍如何使用 sympy 符号求解器准确求解包含四个未知复数节点电压(v₁, v₂, v₃, vₙ)的耦合代数方程组,并提取可用于后续数值计算的浮点结果。
在三相电力系统分析中,常需求解基于基尔霍夫定律建立的复数节点电压方程组。本例中,v₁、v₂、v₃ 和中性点电压 vₙ 相互耦合:前三者各自依赖 vₙ,而 vₙ 又由 v₁–v₃ 反向决定,形成闭合代数系统。直接赋值迭代易发散,且原始代码因变量未定义导致运行错误;正确做法是将其整体视为符号方程组,交由代数求解器精确处理。
使用 sympy.solve() 是最直接可靠的方式。关键步骤如下:
- 声明符号变量:v_1, v_2, v_3, v_n = sp.symbols("v_1 v_2 v_3 v_n");
- 构建标准方程形式(等式右侧为 0):将原表达式移项为 v_i - (...) == 0;
- 调用求解器:传入方程列表与变量列表,返回字典形式解;
- 安全提取数值:通过字典键索引获取 solution[v_1] 等,再转为 NumPy 复数以支持 np.abs() 等运算。
以下是完整可运行代码(已优化可读性与健壮性):
import cmath
import math
import numpy as np
import sympy as sp
# 系统参数初始化
r3 = math.sqrt(3)
pp = cmath.exp(-1j * 2 * math.pi / 3) # a² = e^(-j2π/3)
U = 400.0
U_ph = U / r3
U_a, U_b, U_c = U_ph, U_ph * pp, U_ph * pp**2
# 负载复功率(注意:S = P + jQ,感性负载 Q > 0)
S_HP = 3e3 - 1j * cmath.sqrt((3e3 / 0.95)**2 - (3e3)**2) # 功率因数 0.95 感性
S_PV = -3.6e3 + 0j # 纯有功注入(光伏)
S_EV = 16 * 400 * r3 + 0j # 电动汽车充电(假设单位功率因数)
# 等效阻抗(由 S = U²/Z* ⇒ Z = (U²/S)*)
Z_line = 0.3 + 0.1j
Z_HP = (U_ph**2 / S_HP).conjugate()
Z_PV = (U_ph**2 / S_PV).conjugate()
Z_EV = (U_ph**2 / S_EV).conjugate()
# 声明符号变量
v_1, v_2, v_3, v_n = sp.symbols("v_1 v_2 v_3 v_n")
# 构建方程组:全部整理为 f(v_i, v_n) = 0 形式
eq1 = sp.Eq(v_1, (U_a/Z_line + v_n/Z_HP) / (1/Z_line + 1/Z_HP))
eq2 = sp.Eq(v_2, (U_b/Z_line + v_n/Z_PV) / (1/Z_line + 1/Z_PV))
eq3 = sp.Eq(v_3, (U_c/Z_line + v_n/Z_EV) / (1/Z_line + 1/Z_EV))
eq4 = sp.Eq(v_n, (v_1/Z_HP + v_2/Z_PV + v_3/Z_EV) / (1/Z_line + 1/Z_HP + 1/Z_PV + 1/Z_EV))
# 求解(自动处理复数代数)
solution = sp.solve([eq1, eq2, eq3, eq4], [v_1, v_2, v_3, v_n], dict=True)[0]
# 提取并转换为 NumPy 复数(确保后续数值运算兼容)
v_1_val = complex(solution[v_1])
v_2_val = complex(solution[v_2])
v_3_val = complex(solution[v_3])
v_n_val = complex(solution[v_n])
# 输出相电压幅值(对地电压有效值)
print(f"|v₁ − vₙ| = {np.abs(v_1_val - v_n_val):.0f} V")
print(f"|v₂ − vₙ| = {np.abs(v_2_val - v_n_val):.0f} V")
print(f"|v₃ − vₙ| = {np.abs(v_3_val - v_n_val):.0f} V")✅ 注意事项:
- sp.solve(..., dict=True) 返回字典列表,取 [0] 获取唯一解;
- complex() 强制转换保障与 numpy 函数(如 np.abs, np.angle)无缝对接;
- 若方程高度非线性或存在多重解,可改用 sp.nonlinsolve 或数值求解器 scipy.optimize.fsolve(需提供初值);
- 所有复数运算应统一使用 cmath 或 numpy,避免混用 math.sqrt 处理负数导致 ValueError。
该方法兼具符号精度与工程实用性,适用于含复功率、阻抗耦合的配电网节点电压分析场景。










