数论 | 高斯消元法
高斯消元法 (Gaussian Elimination): 线性代数中的一个算法,可以把矩阵转化为行阶梯形矩阵。用这种方法可以求线性方程组的解。
高斯消元法
我们很早便学习了通过消元求解线性方程组,高斯消元法实际上就是这个方法。只不过它用线性代数的数学语言来描述该过程,利用矩阵的变换来求解线性方程组。为了该笔记更多人能看懂,下面简单介绍一些线性代数的概念。
我们程序实现的时候,只有唯一解的情况可解出方程组的解,无穷解无法得出通解。
补充内容
系数矩阵
对于上述线性方程组,系数构成的矩阵叫做系数矩阵:
系数与常数项构成的矩阵叫做增广矩阵:
初等行变换
下面的三种变换称为矩阵的初等行变换:
- 对调矩阵的两行。
- 以非零常数
乘矩阵某一行的各元。 - 把某一行所有的元素的
倍加到另一行对应的元上去。
对线性方程组的增广矩阵做上述初等行变换,线性方程组的解不变。
行阶梯型矩阵
可画出一条阶梯线,线的下方的元素全为
行最简型矩阵
非零行的第一个非零元为
可以发现,如果我们得到了行最简型矩阵,线性方程组的解就可以直接写出了。
算法过程
- 输入方程的增广矩阵
- 使用初等行变换将其变为行阶梯型矩阵
- 再用初等行变换将其变为行最简型矩阵
- 通过行最简型矩阵输出方程的解
下面详细解释下每步的过程:
使用初等行变换将其变为行阶梯型矩阵
从第一列遍历到最后一列:
- 找到绝对值最大的一行(这个是为了精度更高)
- 将该行换到矩阵最上面
- 将改行第一个数化为
- 将
下面的数全部化为
再用初等行变换将其变为行最简型矩阵
从最后一行遍历到第一行:
- 将该行
上方的数全部化为
示例
我们以下面的线性方程组为例来模拟一遍操作:
- 读入增广矩阵:
- 化为行阶梯型矩阵
- 化为行最简型矩阵
- 输出线性方程组的解
代码
const int MAXN = 110; // 最大方程数
const double EPS = 1e-6; // 浮点误差
int n; // 方程个数
double mat[MAXN][MAXN]; // 增广矩阵
int gauss()
{
int row, col;
for (row = 0, col = 0; col < n; col++)
{
int max_row = row;
for (int i = row; i < n; i++)
if (fabs(mat[i][col]) > fabs(mat[max_row][col]))
max_row = i;
if (fabs(mat[max_row][col]) < EPS)
continue;
for (int i = col; i <= n; i++)
swap(mat[max_row][i], mat[row][i]);
for (int i = n; i >= col; i--)
mat[row][i] /= mat[row][col];
for (int i = row + 1; i < n; i++)
if (fabs(mat[i][col]) > EPS)
for (int j = n; j >= col; j--)
mat[i][j] -= mat[i][col] * mat[row][j];
row++;
}
if (row < n)
{
for (int i = row; i < n; i++)
if (fabs(mat[i][n]) > EPS)
return 2; // 无解
return 1; // 无穷解
}
for (int i = n - 1; i >= 0; i--)
for (int j = i + 1; j < n; j++)
mat[i][n] -= mat[i][j] * mat[j][n];
return 0; // 有唯一解
}
本文采用 CC BY-SA 4.0 许可,本文 Markdown 源码:Haotian-BiJi