2.3 非齐次方程组解集
文章目录
- 反表示法
- 计算机算法
- Python代码
反表示法
非齐次方程组如果系数矩阵的秩小于未知数的个数,那么就有了自由变量,这个时候就需要写出它的解集。对于这种线性代数的基本功,确实有不少算法,比如适合手算的反表示法,适合计算机的算法,还有广义逆法。这里先介绍考试用的反表示法,比如以下方程:
x + y + z = 1 x+y+z=1 x+y+z=1
对于这个方程,有三个未知数,但是只有一个方程,所以就有两个自由变量,那么以 x , y x,y x,y为自由变量,用 x , y x,y x,y来反表示 z z z,就是以下结果:
z = 1 − x − y z=1-x-y z=1−x−y
那么解就是这个样子:
( x y z ) = ( x y 1 − x − y ) \begin{pmatrix}x\\y\\z\end{pmatrix}=\begin{pmatrix}x\\y\\1-x-y\end{pmatrix} xyz = xy1−x−y
到了这一步就是进行自由变量的分离了。于是将上式进一步写成:
( x y z ) = ( x y 1 − x − y ) = ( 0 0 1 ) + ( x 0 − x ) + ( 0 y − y ) \begin{pmatrix}x\\y\\z\end{pmatrix}=\begin{pmatrix}x\\y\\1-x-y\end{pmatrix}=\begin{pmatrix}0\\0\\1\end{pmatrix}+\begin{pmatrix}x\\0\\-x\end{pmatrix}+\begin{pmatrix}0\\y\\-y\end{pmatrix} xyz = xy1−x−y = 001 + x0−x + 0y−y
所以解集就是:
( 0 0 1 ) + ( x 0 − x ) + ( 0 y − y ) = ( 0 0 1 ) + x ( 1 0 − 1 ) + y ( 0 1 − 1 ) \begin{pmatrix}0\\0\\1\end{pmatrix}+\begin{pmatrix}x\\0\\-x\end{pmatrix}+\begin{pmatrix}0\\y\\-y\end{pmatrix}=\begin{pmatrix}0\\0\\1\end{pmatrix}+x\begin{pmatrix}1\\0\\-1\end{pmatrix}+y\begin{pmatrix}0\\1\\-1\end{pmatrix} 001 + x0−x + 0y−y = 001 +x 10−1 +y 01−1
计算机算法
这样反表示,计算并不快,需要一步步拆解,以上面的为例子,进一步研究解的结构,首先看第一部分:
( 0 0 1 ) \begin{pmatrix}0\\0\\1\end{pmatrix} 001
这一部分是所有自由变量都为0的结果,所以它的坐标的前两项都是0,那么这个就很容易用程序求出来,也是第一步要求的向量。再看第二部分的其中一个向量:
y ( 0 1 − 1 ) y\begin{pmatrix}0\\1\\-1\end{pmatrix} y 01−1
这是其余自由变量为0, y y y为1的结果。所以也容易求出来。计算机求解因为强制了系数为1,所以结果中容易出现小数,而反表示法由于是直接反表示拆解的,所以结果中一般不会出现小数,各有各的好处。
不过需要注意行阶梯形的阶梯,如一下方程:
( 1 1 1 1 0 0 1 1 ) x = ( 2 1 ) \begin{pmatrix} 1 & 1 & 1 & 1\\ 0 & 0 & 1 & 1 \end{pmatrix}\bold x= \begin{pmatrix} 2 \\ 1 \end{pmatrix} (10101111)x=(21)
这里有四个未知数, x 1 , x 2 x_1,x_2 x1,x2组成一个阶梯, x 3 , x 4 x_3,x_4 x3,x4组成一个阶梯。 x 1 , x 2 x_1,x_2 x1,x2不能同时是自由变量。等于是说每个阶梯里,至少有一个变量不是自由的。以上面的方程为例子,假如第一个阶梯全部为0,那么方程就变成了:
( 1 1 1 1 ) x = ( 2 1 ) \begin{pmatrix} 1 & 1\\ 1 & 1 \end{pmatrix}\bold x= \begin{pmatrix} 2 \\ 1 \end{pmatrix} (1111)x=(21)
这就成了矛盾方程了。
Python代码
代码比较长,我是以每个阶梯的后几个变量为自由变量的。
# 非齐次线性方程组解集def non_homogeneous_solution(self, values):# 必须加上值组成增广矩阵vectors = copy.deepcopy(self.__vectors)vectors.append(values)augmented = Matrix(vectors)matrix = augmented.to_upper_triangle()n = len(self.__vectors)coefficients = Matrix(matrix.__vectors[0:-1])new_values = matrix.__vectors[-1]rank = coefficients.get_rank(new_values)if rank == n:# 满秩return matrix_utils.solve_upper_triangle(coefficients, new_values)# 不是满秩的return coefficients.solution_from_echelon(new_values)# 直接根据阶梯形求解def solution_from_echelon(self, values):# 先获取特解# 每个阶梯的前n-1个自由,最后一个不自由# 获得一个新方程# 自由的全部为0echelons = self.get_echelons()special = self.particular_solution(echelons, values)# 通解是那些自由变量,一个为1,其余为0free_columns = matrix_utils.free_columns(echelons)solutions = [special]for free_column in free_columns:# 组成一个新矩阵vectors = []for echelon in echelons:vectors.append(self.__vectors[echelon[0]])new_value = matrix_utils.sub(values, self.__vectors[free_column])# 解只是主元的解solution = matrix_utils.solve_upper_triangle(Matrix(vectors), new_value[0:len(echelons)])result = [0] * len(self.__vectors)result[free_column] = 1for i, echelon in enumerate(echelons):result[echelon[0]] = solution[i]solutions.append(matrix_utils.sub(result, special))return solutions# 非齐次方程组特解def particular_solution(self, echelons, values):# 自由变量全部为0的新方程# 必须保证是一个方阵vectors = [self.__vectors[echelon[0]][0:len(echelons)] for echelon in echelons]solution = matrix_utils.solve_upper_triangle(Matrix(vectors), values[0:len(echelons)])# 新方程的解# 特解是拼起来的result = [0] * len(self.__vectors)for i, echelon in enumerate(echelons):# 主元不自由,其余自由result[echelon[0]] = solution[i]return result# 获取矩阵的秩def get_rank(self, values):m = len(self.__vectors[0])n = len(self.__vectors)rank = 0# 非自由变量的集合for i in range(m - 1, -1, -1):# 获取非零元素的列non_zeros = []for j in range(n):if abs(self.__vectors[j][i]) > matrix_utils.MAX_ERROR:non_zeros.append(self.__vectors[j][i])if len(non_zeros) == 0 and not matrix_utils.is_zero(values[i]):raise Exception('方程为矛盾方程组')elif len(non_zeros) == 1:rank += 1else:rank += 1return rank# 获取阶梯数组def get_echelons(self):echelons = []# 循环列echelon = []level = 0for j, e in enumerate(self.__vectors):m = len(e)# 如果是最后一行if level == m - 1:echelon.append(j)elif matrix_utils.is_zero(e[level + 1]) and not matrix_utils.is_zero(e[level]):echelon.append(j)else:level += 1echelons.append(echelon)echelon = [j]echelons.append(echelon)return echelons
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
