简介:这份《高等代数》考试复习资料对应中国人民大学历年期末试题,覆盖行列式、矩阵逆与伴随矩阵、线性相关与无关、秩与线性方程组解结构、线性映射标准矩阵等核心考点,并附有矩阵方程、分块矩阵求逆等典型题目解析。适合数学及相关专业本科生期末备考,也可作为考研基础阶段刷题与自查材料。资源为单个PDF文档,体积约1.5MB,方便打印或导入平板做笔记。目前已有311人学习使用。除试卷原题外,内容还涉及代数余子式与行列式展开、伴随矩阵性质、齐次线性方程组基础解系、通解与特解关系、矩阵幂运算及矩阵方程解法等易错重难点;对照题目逐一梳理知识点,有助于快速定位薄弱环节并形成系统化解题思路。
1. 这份高等代数复习资料,把线性代数的主线压在了四类题上
拿到这份中国人民大学《高等代数》考试复习 PDF,第一反应是题老,第二反应是考点集中得可怕。两套期末卷子翻下来,行列式按行展开、伴随矩阵与逆矩阵、线性方程组的秩判定、多项式整除与有理根,几乎把所有高分值题目都串在这四条线上。对正在备考高代期末或考研数学的读者,这是一份可以直接用来对答案的真题集;对平时写数值代码、做矩阵运算的工程师,里面反复出现的“代数余子式求和”“分块矩阵求逆”“带参方程组分类讨论”恰恰是手算和程序验证最容易出错的地方。后面的内容全部围绕这套试卷展开,每类题都先讲判定依据,再给可复现的代码与参数说明,最后指出考场和工程里最常见的坑。
2. 行列式与代数余子式:先看懂替换定理,再谈五阶展开
2.1 代数余子式按行求和:比逐项展开快一个量级的等价替换
2005 级填空题第 1 题给了一个 5 阶行列式,要求计算 A41 + A42 + A43 + A44 与 A44 + A45,其中 A4j 是第 4 行第 j 个元素的代数余子式。很多人的第一反应是把 5 阶行列式硬展开,再按定义求每个代数余子式,这在小规模题目里勉强能算,但既慢又容易漏符号。这里有一个更直接的结论:第 i 行代数余子式的线性组合,等于把原行列式第 i 行替换成对应系数后重新计算的行列式。
原因是行列式按某一行展开时,展开式对所有行都成立。如果想把 A41 到 A44 直接相加,就相当于把第 4 行全部替换成 1,此时新行列式按第 4 行展开,得到的恰好是 A41 + A42 + A43 + A44。同理,A44 + A45 只需要把第 4 行第 4、5 列置为 1,其余位置置为 0,再求行列式。这个替换技巧不但适用于求和,也适用于带权求和,本质上是把“逐项计算余子式”变成了“一次行列式计算”。
| 目标表达式 | 等价替换方式 |
|---|---|
| A41 + A42 + A43 + A44 | 第 4 行全部替换为 1,其余行不变,求行列式 |
| A44 + A45 | 第 4 行第 4、5 列为 1,其余为 0,求行列式 |
| 2A41 - 3A43 | 第 4 行替换为 (2, 0, -3, 0, 0),求行列式 |
用这个思路处理资料里另一道“设 D 为 4 阶行列式,求 A14 + A24 + A34 + A44”的题也是一样:把第 4 列全部换成 1 再算行列式,答案直接读出来。实际阅卷时,这类填空题的答案往往就藏在新行列式的对角线乘积里,手算速度能快出不少。
2.2 从扫描 PDF 到 SymPy 验证:OCR 乱码是第一个坑
这套 PDF 是扫描版转出来的,矩阵里的 3 和 5、0 和 8 经常混在一起,直接对着屏幕抄数字很容易抄错。我一般会先用命令行工具把 PDF 文本抽出来,再人工对一遍行列式里的数字:
pdftotext -layout 高等代数考试复习.pdf 高等代数.txt grep -n "5 阶行列式" 高等代数.txt-layout参数保留原始排版,能让矩阵结构尽量不被拆散。抽出来的文本仍然会有大量乱码,比如“51234522211273”这类连续数字,需要按行列式维度手动切分。把矩阵整理干净之后,再用 SymPy 做验证比较稳妥:
from sympy import Matrix, symbols D = Matrix([ [5, 1, 2, 3, 4], [5, 2, 2, 2, 1], [1, 2, 7, 3, 4], [1, 2, 4, 5, 1], [1, 1, 2, 4, 3] ]) # 第4行替换为全1,求 A41+A42+A43+A44 row_replaced = D.copy() row_replaced[3, :] = [1, 1, 1, 1, 1] print("A41+A42+A43+A44 =", row_replaced.det()) # 第4行第4、5列为1,求 A44+A45 col_replaced = D.copy() col_replaced[3, :] = [0, 0, 0, 1, 1] print("A44+A45 =", col_replaced.det()) # 直接枚举代数余子式做交叉验证 s = sum(D.cofactor(3, j) for j in range(4)) print("枚举验证 =", s)Matrix构造时按行传入列表,cofactor(3, j)返回第 4 行第 j+1 列的代数余子式,索引从 0 开始。替换行之后再det(),结果与枚举求和一致,说明替换定理没有用错。这里的参数说明只有一条要记住:SymPy 的行列和列都是从 0 计数,而试卷里从 1 计数,换算时别把第 4 行写成cofactor(4, j),那会越界或者算到第 5 行。
2.3 锯齿形行列式:按第一行展开后只剩下一个非零项
2006—2007 学年试卷里出现了一个形如0001 / 0002 / 0020 / 0500 / 2006的锯齿形行列式,这类题的通用做法是连续按第一行或最后一列展开。以 5 阶为例,第一行只有一个非零元素,其余元素都是 0,展开后剩下一个 4 阶子式,而这个子式仍然保持锯齿形状,于是可以递推。
我一般会先写出 D_n 与 D_{n-2} 的关系,再叠乘到边界条件。这样处理的好处是不需要展开完整行列式,每次只保留一个非零项。工程上如果遇到上百阶的稀疏三角矩阵,直接用scipy.linalg.det或numpy.linalg.det也能算,但理解这个递推过程对判断稀疏矩阵的零块结构很有帮助。
这里的易错点在于:每展开一次,符号会多一个 (-1) 的幂次,叠乘时必须把每次展开的符号单独记下来。很多人在这一步丢掉负号,导致最终答案差一个符号。我的习惯是先在草稿纸上写出 D_n = ... D_{n-2} 的递推式,再代入 n 的具体值做两层验证。
2.4 代数余子式展开的常见误用与符号陷阱
代数余子式 Aij 与余子式 Mij 只差一个符号因子,Aij = (-1)^(i+j) Mij。求“第 4 行代数余子式之和”时,如果直接把第 4 行替换成 1 再去计算行列式,结果天然包含了符号因子,不需要额外处理。但如果手算时先求 M4j 再相加,就必须逐个补上 (-1)^(4+j)。
另一个常见的误用是混淆“某行代数余子式之和”与“某行元素乘以该行代数余子式之和”。后者才是行列式按行展开的原始形式,结果等于 det(A);前者相当于做了一次行替换。这两个概念在选择题里经常成对出现,判断时先看求和对象是 Aij 还是 aij Aij,符号和结果完全不同。
还要注意:对矩阵做初等行变换之后,原矩阵的代数余子式通常会发生改变,不能把变换后的矩阵当成原矩阵去求余子式。如果题目明确要求某个位置的代数余子式,就在原始矩阵上算,不要先化简再算。
3. 伴随矩阵与逆矩阵:分块求逆、矩阵方程与可逆性证明
3.1 伴随矩阵三大恒等式:把 A* 统一化成 A 的逆
伴随矩阵相关内容在试卷里出现频率很高,2005 级填空第 3 题直接考察了带伴随矩阵的复杂表达式求值。核心恒等式只有一个:
A · A* = A* · A = |A| · E
由这个式子可以推出三个常用结论。第一,若 A 可逆,则 A* = |A| A^(-1),这是把伴随矩阵替换成逆矩阵的统一入口。第二,|A*| = |A|^(n-1)。第三,A 不可逆时,A·A* = 0 这个结论在某些证明题里反而比可逆情形更常用。
2005 级那道题给的条件是 |A| = 1/3,要求计算 ((1/4 A)^(-1) - 15 A*)^(-1) 的值。遇到这种题,我建议先把所有伴随矩阵都换成 |A| A^(-1),再把所有常数倍数合并:
from sympy import symbols # |A| = 1/3 detA = symbols('detA') # 统一替换:A* = detA * A^{-1} # 原式 = (4 A^{-1} - 15 * detA * A^{-1})^{-1} # = ((4 - 15*detA) * A^{-1})^{-1} coef = 4 - 15 * Rational(1, 3) print("系数 4 - 15|A| =", coef) # 系数为 -1,所以原式 = -A逻辑说明:(1/4 A)^(-1)等于4 A^(-1),15A* 替换为15 * (1/3) A^(-1),合并后系数是 -1,所以整个逆等于 -A,答案取行列式或对应元素即可。这个化简顺序比先展开括号再合并要清晰得多,凡是出现 A* 与逆矩阵混合的题目,都先把 A* 消掉。
3.2 分块矩阵求逆:先定位零块,再套公式
第六大题给出的分块矩阵在扫描件里排版已经乱了,常见形式是 D = [[A, 0], [C, B]] 或 [[A, C], [0, B]],其中 A、B 分别可逆。求逆公式可以归结为两类:
| 分块形式 | D 的逆矩阵 |
|---|---|
| [[A, 0], [C, B]] | [[A^(-1), 0], [-B^(-1) C A^(-1), B^(-1)]] |
| [[A, C], [0, B]] | [[A^(-1), -A^(-1) C B^(-1)], [0, B^(-1)]] |
口诀是“对角块各取逆,非对角块取负的从左往右夹乘”。第二问给了一个具体 4 阶矩阵,先用 SymPy 验证公式再套数字:
from sympy import Matrix, eye A = Matrix([[1, 1], [2, 3]]) # 零块位置按 [[A, 0], [C, B]] 组织 C = Matrix([[1, 0], [0, -2]]) B = Matrix([[2, 5], [1, 3]]) D = Matrix([[A, Matrix.zeros(2)], [C, B]]) D = D.reshape(4, 4) D_inv = D.inv() # 检查 D * D_inv 是否为单位阵 print((D * D_inv).evalf(3))验证时把乘回去的结果与单位矩阵做差,如果每个元素绝对值小于 1e-10 就说明求逆正确。注意Matrix.zeros(2)生成 2 阶零矩阵,reshape(4, 4)把分块结构展平成完整矩阵。工程里用numpy.linalg.inv也能直接算,但分块公式的价值在于:当 A 和 B 的规模很大时,只对两个小块求逆,计算量从 O(n^3) 降到 O(k^3 + r^3)。
3.3 矩阵方程 AXB = C 的求解顺序:左右乘不能换
矩阵方程题的已知条件是 AXB = C,但扫描件里 C 矩阵的数字丢失了,只保留了 A 和 B。解法本身不依赖 C 的具体值,关键是操作顺序:
| 方程形式 | 操作方法 | 结果 |
|---|---|---|
| AX = B | 左乘 A^(-1) | X = A^(-1) B |
| XA = B | 右乘 A^(-1) | X = B A^(-1) |
| AXB = C | 左乘 A^(-1),右乘 B^(-1) | X = A^(-1) C B^(-1) |
from sympy import Matrix A = Matrix([[1, 1, 1], [0, 2, 2], [1, 1, -1]]) B = Matrix([[1, -1, 1], [1, 1, 0], [2, 2, 1]]) # 假设 C 为与 A、B 同阶的单位阵 C = Matrix.eye(3) X = A.inv() * C * B.inv() print("X =", X)左右乘的次序决定了公式的形态,先左乘再右乘与先右乘再左乘结果通常不相等。如果题目里只有 AX = B 而没有 C,那只需要左乘;如果两个逆矩阵都在,就要确认哪一个在左边。检查方法是把 X 代回原方程,看 AXB 是否等于 C,这一步在任何数值环境里都值得做。
3.4 由 A^m = E 推出 B^m = E:转置与逆的交换顺序
最后一道 8 分证明题说:设 n 阶方阵 A = (a_ij) 满足 A^m = E,B = (A_ij),其中 A_ij 是行列式 A 中元素 a_ij 的代数余子式,证明 B^m = E。这里要特别注意 B 的定义,B 的第 (i, j) 个元素是 A_ji 的代数余子式,也就是 B 等于 (A*)^T 而不是 A* 本身。
证明链条可以这样组织:A^m = E 说明 A 可逆,且 det(A)^m = 1。由 A* = det(A) A^(-1),得 (A*)^T = det(A) (A^(-1))^T。对两边取 m 次方,转置与逆运算是可交换的,所以 ((A^(-1))^T)^m = ((A^m)^(-1))^T = E。同时 det(A)^m = det(A^m) = det(E) = 1,因此 B^m = E。这个结论对后续章节理解分块与可逆性很有用,所以放在这里一起记忆。
4. 线性相关与线性方程组解的结构:秩判定法贯穿始终
4.1 三个秩,定性所有解的情况
2005 级和 2006—2007 学年各有一道十几分的大题专门讨论参数取何值时方程组无解、有唯一解或有无穷多解。这类题的标准工具是系数矩阵的秩 r(A) 和增广矩阵的秩 r(A|b),对照关系如下:
| 条件 | 结论 |
|---|---|
| r(A) < r(A | b) |
| r(A) = r(A | b) = n |
| r(A) = r(A | b) < n |
第二个条件里 n 是未知量个数,不是方程个数。当方程组有 n 个未知量、m 个方程时,r(A) 最多是 min(m, n)。选择题里说的“有唯一解的充分必要条件”,本质上是要求 r(A) = n 且 β 属于 A 的列空间,两者缺一不可。
4.2 线性相关判定:把“存在一组不全为零的系数”变成行列式
2005 级填空第 6 题给了一个经典结论:α1, α2, α3 线性无关,那么 α1 - a α2、α2 - b α3、α3 - c α1 线性相关的充要条件是 abc = 1。这类题不需要逐个试探系数,而是把新向量组写成旧向量组的线性组合:
Beta = Alpha · C
其中 Beta 相关当且仅当变换矩阵 C 奇异,即 det(C) = 0。以这道题为例,组合矩阵的行列式展开后就是 abc - 1 = 0。工程里判断一组数值向量是否线性相关,也常用同样思路构造矩阵后求秩或条件数,但手算时行列式仍然是最直接的判据。SymPy 里可以用Matrix.det()直接展开验证:
from sympy import symbols, Matrix a, b, c = symbols('a b c') # 变换矩阵 C 的行是线性组合系数 C = Matrix([[1, -a, 0], [0, 1, -b], [-c, 0, 1]]) print("det(C) =", C.det().expand())输出结果是a*b*c - 1,所以相关的充要条件是a*b*c - 1 = 0,即 abc = 1。这里的参数说明:C的构造规则是把新向量按“哪些旧向量参与了组合”填入对应列,如果顺序颠倒,行列式只差符号,不影响判定条件。掌握这个矩阵化流程之后,无论参数怎么换,都能直接套用。
4.3 基础解系与通解:先求特解,再补零空间
选择题里给了四个形如 k1γ1 + k2γ2 + ... 的通解表达式,要求判断哪个是非齐次方程组 AX = β 的通解。正确形式一定是“一个特解 + 导出组基础解系的线性组合”。判断选项时先检查两个条件:非齐次部分是否代入后得到 β,齐次部分是否线性无关且个数等于 n - r(A)。
具体实现上,SymPy 提供了两个现成函数,一个解非齐次方程组,一个求零空间:
from sympy import Matrix, linsolve, symbols x1, x2, x3, x4 = symbols('x1 x2 x3 x4') A = Matrix([[1, 1, 1, -1], [3, 2, 1, 1], [1, 1, -2, -3], [2, 1, -3, 4]]) b = Matrix([2, 3, 6, -1]) # 求非齐次特解 solutions = linsolve((A, b), x1, x2, x3, x4) print("通解:", solutions) # 求导出组的基础解系 null_basis = A.nullspace() print("基础解系:", null_basis)linsolve返回解集的参数化表达,nullspace返回一组零空间基向量。注意通解里的自由参数个数必须等于 A 的列数减秩,也就是4 - A.rank()。许多错误选项就是在自由参数个数上做了手脚,要么少了一个,要么把特解和基础解系的系数混在一起。
4.4 带参方程组:用符号增广矩阵找临界值
第五大题的方程组带有 a 和 b 两个参数,直接代入数值消元会丢信息。正确做法是把 a、b 当作符号放到增广矩阵里,做行阶梯形后观察主元位置:
from sympy import Matrix, symbols, solve a, b = symbols('a b') A_aug = Matrix([ [1, 1, 1, -1, 2], [3, 2, 1, 1, 3], [1, 1, -2, -3, 6], [2, 1, -3, a, -b] ]) rref_matrix, pivot_cols = A_aug.rref() print("行最简形:") print(rref_matrix) print("主元列:", pivot_cols)rref()会返回行最简形以及主元所在的列号。如果最后一行形如[0, 0, 0, 0, f(a, b)],那么当 f(a, b) = 0 时方程组有无穷多解,否则无解;如果主元列覆盖了全部四个未知量,则方程组有唯一解。临界值就是solve(f, a, b)得到的参数组合。这里最容易踩的坑是:符号矩阵做rref()时可能会除以含参数的表达式,导致 a = 0 或 b 的某个取值被当作默认可除条件丢掉,所以拿到结果后要人工检查主元里是否出现了参数在分母的情况。
5. 多项式整除与有理根:综合除法、重因式与公共根的完整分析
5.1 综合除法的边界:只适合一次因式
2006—2007 学年填空第 3 题要求用综合除法求 f(x) = x^4 - 17 除以 g(x) = x + 2 的商式和余式。综合除法的操作是:系数从高次到低次排列,逐项乘加,最后一个是余数。4 次式除以一次式,商是 3 次式:
from sympy import symbols, div from sympy.abc import x f = x**4 - 17 g = x + 2 q, r = div(f, g, x) print("商式:", q) print("余式:", r)输出商式为 x^3 - 2x^2 + 4x - 8,余式为 -1。这里的div返回 (商, 余) 两个多项式对象,整个过程等价于手算综合除法。注意综合除法只适用于除式为一次因式的情况,如果除式是 x^2 + 2 这样的二次式,就不能直接把系数拿来做简单的乘加循环,必须回退到多项式长除法。
5.2 重因式判定:求 gcd(f, f') 就能看见 n = 4 的临界点
思考题第一题问正整数 n 取何值时 f(x) = (x+1)^n - x^n - 1 有重因式,并强调不要用辗转相除。重因式的判定标准是 gcd(f, f') 的次数至少为 1,等价于 f 与 f' 存在公共根。用 SymPy 快速扫描 n 的取值:
from sympy import gcd, diff, factor from sympy.abc import x for n in range(2, 9): f = (x + 1)**n - x**n - 1 g = gcd(f, diff(f, x)) print("n =", n, "gcd 次数:", g.as_poly().degree())当 n = 4 时,f = (x+1)^4 - x^4 - 1 展开为 4x^3 + 6x^2 + 4x,gcd(f, f') 是一次多项式,说明存在重因式;其它 n 值 gcd 降到 0 次,说明没有重根。这题的快速手算思路是设公共根为 r,联立 f(r) = 0 与 f'(r) = 0,消去指数项后得到一个关于 n 的方程,解出 n = 4。
5.3 公共有理根的试根表:先枚举后验证
第二道思考题给出两个整系数多项式,要求找出使它们有公共有理根的整数 a、b。有理根定理支持用枚举法缩小范围:若既约分数 p/q 是整系数多项式的根,则 p 整除常数项,q 整除首项系数。题目里 f 和 g 的常数项分别是 -1 和 -4c,首项系数是 6 和 1,候选根范围非常有限。
from itertools import product from sympy.abc import x from sympy import symbols, Poly, Rational a, b = 5, 2 # 已知答案,用于验证枚举逻辑 f = 6*x**4 + 3*x**3 + a*x**2 + b*x - 1 g = x**4 - 2*a*x**3 + Rational(3, 4)*x**2 - 5*b*x - 4 # 常数项因数为 p,首项系数因数为 q p_candidates = [1, -1] q_candidates = [1, -1, 2, -2, 3, -3, 6, -6] roots = [] for p, q in product(p_candidates, q_candidates): r = Rational(p, q) if f.subs(x, r) == 0 and g.subs(x, r) == 0: roots.append(r) print("公共有理根:", roots)实际执行时先代入每个候选根,只有同时让 f 和 g 为零的候选才保留。a = 5、b = 2 是题目给的目标值,枚举结果会与预期一致。这里的参数说明:product生成 p 和 q 的全部组合,候选集合越小,枚举速度越快。真正的工程技巧是不要一上来就调 SymPy 的roots,先把候选根缩到十来个再逐个代入,速度更快而且不容易漏解。
5.4 把带参多项式问题收敛成一个可复用流程
上面几节的方法可以统一成一个流程:先确定有理根候选集合,再代入参数表达式验证公共根,最后用 gcd(f, f') 检查重因式。对这道思考题,把 a、b 设成符号做一次完整扫描:
from sympy import symbols, Poly, Rational from sympy.abc import x a_sym, b_sym = symbols('a b') p_candidates = [1, -1] q_candidates = [1, -1, 2, -2, 3, -3, 6, -6] results = [] for p, q in product(p_candidates, q_candidates): r = Rational(p, q) f_val = Poly(6*x**4 + 3*x**3 + a_sym*x**2 + b_sym*x - 1, x) g_val = Poly(x**4 - 2*a_sym*x**3 + Rational(3, 4)*x**2 - 5*b_sym*x - 4, x) eq1 = f_val.eval(r).as_expr() eq2 = g_val.eval(r).as_expr() solutions = solve([eq1, eq2], [a_sym, b_sym], dict=True) for sol in solutions: if sol[a_sym].is_integer and sol[b_sym].is_integer: results.append((r, sol[a_sym], sol[b_sym])) print("整数参数与公共根:", results)Poly(...).eval(r)计算多项式在 r 处的取值,得到的是包含 a、b 的表达式。solve返回满足 f(r) = 0 且 g(r) = 0 的参数组合,再用is_integer过滤出整数解。对扫描得到的每个公共根做代入验证,与直接用gcd判断重因式的结论互为印证。n 从 2 换成 5 时 gcd 次数回到 0,这说明重因式只出现在参数取值恰好使公共根成立的那些点上,而不是一个持续存在的结构性质。
本文还有配套的精品资源,点击获取