
本文介绍如何利用 SymPy 的 solve() 函数,准确求解由节点电压法导出的含复数系数、相互耦合的四元非线性代数方程组,并提取可直接用于数值计算的浮点型结果。
本文介绍如何利用 sympy 的 `solve()` 函数,准确求解由节点电压法导出的含复数系数、相互耦合的四元非线性代数方程组,并提取可直接用于数值计算的浮点型结果。
在三相不平衡配电网建模中,常需同时求解多个节点电压(如 $v_1, v_2, v_3$)与中性点电压 $v_n$,其表达式彼此隐式关联——每个相电压依赖于 $v_n$,而 $v_n$ 又由三相电流平衡反推得出。这类问题无法通过简单顺序赋值求解(原代码中直接使用未定义的 v_n 会导致 NameError),必须作为整体方程组求解。
SymPy 提供了强大的符号代数求解能力,特别适合处理复数域中的精确代数系统。核心步骤如下:
- 声明符号变量:使用 sp.symbols() 定义 $v_1, v_2, v_3, v_n$ 为符号对象;
- 构建方程列表:将原始表达式移项为“左端 − 右端 = 0”形式(例如 v_1 - ((U_a/Z) + (v_n/Z_HP)) / (...)),确保 solve() 正确识别等式关系;
- 调用 sp.solve():传入方程列表与待求变量列表,返回字典形式的解析解;
- 提取并转为数值:从解字典中取出各变量,其默认为 SymPy 表达式;调用 .evalf() 或直接参与 np.abs() 等 NumPy 运算时会自动数值化(推荐显式调用 .evalf() 提升可读性与可控性)。
以下是完整、可运行的解决方案:
import cmath
import math
import numpy as np
import sympy as sp
# 参数初始化(三相系统基准)
r3 = math.sqrt(3)
pp = cmath.exp(-1j * math.pi * 2 / 3) # a-b-c 相序旋转因子
U = 400
U_ph = U / r3
U_a = U_ph
U_b = U_a * pp
U_c = U_b * pp
# 负载复功率(S = P + jQ),注意 PV 为发电(负有功),EV 为纯阻性负载
S_HP = 3e3 - cmath.sqrt((3e3 / 0.95) ** 2 - 3e3 ** 2) * 1j # 感性负荷,cosφ=0.95
S_PV = -3.6e3 + 0j # 光伏发电
S_EV = 16 * 400 * r3 + 0j # 电动汽车充电(假设单位功率因数)
# 线路与等效阻抗(Ω)
Z = 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")
# 构建四元方程组(全部移项至左侧)
equations = [
v_1 - ((U_a/Z) + (v_n/Z_HP)) / ((1/Z) + (1/Z_HP)),
v_2 - ((U_b/Z) + (v_n/Z_PV)) / ((1/Z) + (1/Z_PV)),
v_3 - ((U_c/Z) + (v_n/Z_EV)) / ((1/Z) + (1/Z_EV)),
v_n - ((v_1/Z_HP) + (v_2/Z_PV) + (v_3/Z_EV)) / ((1/Z) + (1/Z_HP) + (1/Z_PV) + (1/Z_EV))
]
# 求解方程组
solution = sp.solve(equations, [v_1, v_2, v_3, v_n])
# 提取数值解(自动转换为 complex 类型,支持后续 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"\n |v1−vn| = {np.abs(v_1_val - v_n_val):.0f} V")
print(f"\n |v2−vn| = {np.abs(v_2_val - v_n_val):.0f} V")
print(f"\n |v3−vn| = {np.abs(v_3_val - v_n_val):.0f} V")✅ 关键注意事项:
- 避免循环依赖赋值:原始代码中 v_1, v_2, v_3 直接引用未定义的 v_n,属于语法错误;必须整体建模求解。
- 复数精度处理:SymPy 解可能含极小虚部(如 1e-20j),complex() 转换后由 NumPy 的 abs() 自动处理,无需手动 np.real() 截断。
- 性能提示:对于大规模系统,建议改用数值方法(如 scipy.optimize.fsolve);SymPy 更适用于中小规模、需解析洞察或参数化分析的场景。
- 扩展性建议:若需批量分析不同功率因数或负载组合,可将 S_HP, S_PV 等设为符号参数,使用 sp.solve(..., dict=True) 获取参数化解。
通过本方法,你不仅能获得高精度复数解,还可无缝集成至后续的潮流分析、谐波评估或保护整定计算流程中。










