为何使用numpy.linalg.solve无法正确求解线性方程组?
嘿,这个问题其实很常见——你犯了一个新手容易踩的小错误:系数矩阵的行和列完全搞反了,这才导致linalg.solve给出了不符合预期的结果。
先理清楚正确的矩阵形式
原方程组是:
x + y + z = 2
2x - 6y - z = -1
3x - 2z = 8
线性方程组的标准矩阵形式是 A * X = B,其中:
A是系数矩阵,每一行对应一个方程的系数:A = np.array([ [1, 1, 1], # 第一个方程:1*x + 1*y + 1*z [2, -6, -1], # 第二个方程:2*x + (-6)*y + (-1)*z [3, 0, -2] # 第三个方程:3*x + 0*y + (-2)*z(y的系数是0别漏了) ])B是常数项向量:np.array([2, -1, 8])X是我们要求的未知数向量[x, y, z]
而你构造的a是:
a = np.array([[1,2,3],[1,-6,0],[1,-1,-2]])
这个矩阵的每一列才是原方程的系数,相当于你把方程组写成了 X * A = B 的行向量形式,但numpy.linalg.solve默认处理的是列向量形式的A*X=B,自然得不到正确结果。
为什么调换dot顺序能得到正确结果?
当你执行 x = np.dot(b, np.linalg.inv(a)) 时,其实是在求解 X * a = b(行向量形式),而你的a恰好是正确系数矩阵的转置,这个操作刚好歪打正着匹配了原方程组的结构,所以得到了正确结果。但这是巧合,不是规范的解法。
修正后的正确代码
用linalg.solve的正确写法应该是这样的:
import numpy as np from numpy.linalg import solve, LinAlgError # 正确的系数矩阵 A = np.array([ [1, 1, 1], [2, -6, -1], [3, 0, -2] ]) B = np.array([2, -1, 8]) try: X = solve(A, B) except LinAlgError: X = np.linalg.lstsq(A, B)[0] print(X) # 输出:[ 2. 1. -1.] # 用np.allclose代替==,避免浮点精度导致的判断错误 print(np.allclose(np.dot(A, X), B)) # 输出:True
这里用np.allclose代替直接的==,因为浮点计算可能存在微小的精度误差,直接用==偶尔会得到False,而allclose会判断两个数组是否在允许的误差范围内相等,更稳妥。
总结一下
- 构造系数矩阵时,一定要确保每一行对应一个方程的系数,和原方程组的顺序完全匹配
numpy.linalg.solve只处理A*X=B的列向量形式,不要搞反行和列- 浮点数组的比较尽量用
np.allclose,避免直接用==
内容的提问来源于stack exchange,提问作者Porada Kev
相关产品推荐
相关产品推荐

