# 解方程 · 精确的根，与一堵数学的墙

> solve 给出方程的精确根：二次是求根公式，三次四次也有（繁琐的）根式解。但到了五次，一堵墙立在那里——Abel-Ruffini 定理证明：五次以上方程没有通用的根式解。这一章看符号求解的威力，以及计算机如何「知道」并诚实面对这堵墙。

- 作者：David（道雾轩）
- 专栏：符号计算的艺术（https://daiw.org/manual/symbolic-computing.md）
- 最后更新：2026-09-13
- 原文：https://daiw.org/manual/symbolic-computing/equation-solving
- 转载与引用：请注明出处并附原文链接（https://daiw.org/about/copyright）

# 解方程 · 精确的根，与一堵数学的墙

进入精确求解。解方程是符号计算最「解气」的能力之一——不是逼近一个根，而是给出**精确的根**。但这条路走到五次方程时，会撞上数学史上一堵著名的墙。这一章，既看它的威力，也看它如何诚实地面对自己的极限。

## solve：精确的根

`solve` 求方程的精确解：

```python
from sympy import *
x = symbols('x')

print(solve(x**2 - 2, x))     # [-sqrt(2), sqrt(2)]   —— 精确,不是 ±1.414
print(solve(x**2 + 1, x))     # [-I, I]               —— 复数根也精确
```

$x^2-2=0$ 的根是**精确的** $\pm\sqrt2$，而不是[数值解](https://daiw.org/manual/numerical-computing/newton)给的 $\pm1.41421356$；$x^2+1=0$ 干脆给出虚数根 $\pm i$。更漂亮的是，它能解**带符号系数**的方程，直接吐出你中学背过的**求根公式**：

```python
a, b, c = symbols('a b c')
print(solve(a*x**2 + b*x + c, x))
# [(-b - sqrt(b**2 - 4*a*c))/(2*a), (-b + sqrt(b**2 - 4*a*c))/(2*a)]
```

$\dfrac{-b\pm\sqrt{b^2-4ac}}{2a}$——一字不差。这是符号计算的典型场景：**不是解某一个具体方程，而是推导出一整个公式。**

## 三次、四次：繁琐但仍有根式解

二次有求根公式，三次、四次也有（卡尔达诺公式、费拉里公式），只是**繁琐得多**。SymPy 照样能给：

```python
sols = solve(x**3 - 2, x)      # x³=2 的三个立方根(1 实 2 复),都用根式精确表示
print(sols[0])                  # 2**(1/3)
```

$x^3=2$ 的三个根——一个实的 $\sqrt[3]2$ 和两个复的——**都能用根式（$\sqrt[3]{\ }$、$i$、$\sqrt3$）精确写出**。四次也一样，虽然公式长到没人愿意手写，但**存在**，CAS 能给。

## 五次的墙：Abel-Ruffini 定理

到五次方程，天变了：

```python
print(solve(x**5 - x + 1, x))
# [CRootOf(x**5 - x + 1, 0), CRootOf(x**5 - x + 1, 1), ...]  —— 不是根式!
```

SymPy **没有**给出根式解，而是返回一串 `CRootOf`。这不是它偷懒——是一条深刻的数学定理：

<Callout type="info">
  **Abel-Ruffini 定理（1824）：五次及以上的一般多项式方程，没有通用的「根式解」。** 也就是说，不存在一个像求根公式那样、只用**加减乘除和开方**就能表达任意五次方程根的公式——这是被**证明**的不可能，不是「还没找到」。这堵墙背后，是 19 世纪 Évariste Galois 创立的**群论 / Galois 理论**：一个方程能否用根式解，取决于它的「对称性群」的结构。五次方程的对称群「太复杂」（$S_5$ 不可解），于是根式无能为力。

  所以计算机**知道**这堵墙的存在。面对五次，它不硬凑，而是诚实地用 `CRootOf(多项式, k)` 表示「**这个多项式的第 k 个根**」——这仍是一个**精确**的符号对象，能[数值](https://daiw.org/manual/symbolic-computing/symbolic-vs-numeric)地算到任意精度，只是**无法用根式写出**。这和[积分那章](https://daiw.org/manual/symbolic-computing/symbolic-integration)的 `erf` 异曲同工：**当已有的符号不够用，就诚实地造一个新符号精确承载它。**
</Callout>

```python
r = CRootOf(x**5 - x + 1, 0)
print(N(r, 20))    # -1.1673039782614186843   —— RootOf 能精确求值到任意位数
```

## 超越方程：无穷多解怎么办

再看含三角、指数的**超越方程**，它可能有**无穷多**解。这时 `solve` 会力不从心，要用更严谨的 `solveset`——它返回一个**解集**，能表示「无穷多」：

```python
print(solveset(sin(x), x, domain=S.Reals))
# Union(ImageSet(Lambda(_n, 2*_n*pi), Integers), ImageSet(...2*_n*pi + pi...))
```

$\sin x=0$ 的解是**所有** $n\pi$（$n$ 取任意整数）。`solveset` 用 `ImageSet` 精确表达这个无穷集合——这是 `solve`（只返回有限个解）做不到的。**方程的解可能是无穷集，符号系统用「集合」这个精确语言来承载它。**

## 方程组呢

单个方程说完了。**多元多项式方程组**的精确求解，我们[已经见过](https://daiw.org/manual/symbolic-computing/groebner)——`solve` 内部用 [Gröbner 基](https://daiw.org/manual/symbolic-computing/groebner)三角化，再逐个回代，一次性给出全部精确解。符号求解的这套能力（单方程根式解 + Abel-Ruffini 的诚实 + 方程组的 Gröbner），合起来就是「精确地解方程」的完整图景。

## 小结与下一章

**`solve` 给出精确根**：二次直接是求根公式（还能解带符号系数的），三次四次有繁琐的根式解。但 **Abel-Ruffini 定理**证明：**五次以上无通用根式解**——计算机诚实地用 `CRootOf`（第 k 个根，可精确求值）表示，背后是 Galois 理论。超越方程的无穷解集用 `solveset` / `ImageSet` 承载；方程组走 [Gröbner](https://daiw.org/manual/symbolic-computing/groebner)。**认清「哪些能写成根式、哪些不能」，是符号求解的智慧。**

解方程离不开线性代数。下一章看**符号线性代数**——精确的行列式、逆、特征值。而这里藏着一个把[孪生专栏「打脸」](https://daiw.org/manual/numerical-computing/eigenvalues)的漂亮回扣：数值篇千叮万嘱「别用特征多项式求特征值」，符号篇却正大光明地这么干。为什么？👉 [符号线性代数](https://daiw.org/manual/symbolic-computing/symbolic-linalg)。

## 参考文献

- [1] Niels Henrik Abel (1824) / Paolo Ruffini (1799) —— 五次方程根式不可解。
- [2] Ian Stewart.《Galois Theory》—— 方程可解性与群论，极佳的普及。
- [3] SymPy 文档.「solve, solveset, CRootOf.」https://docs.sympy.org/latest/modules/solvers/solvers.html
