数论——10
作者:
就是要AC
,
2021-04-29 11:05:00
,
所有人可见
,
阅读 338
10. 高斯消元
一般步骤:
枚举每一列
step1: 找到当前列绝对值最大的一行.
step2: 将此行换至最上面一行(还未处理好的行中的最上面的那行).
step3: 将该列当前行的第一个数变为 1
step4: 将当前列最大行以下的左右行变为 0
step1 - step4主要目的为化行列式为上三角行列式,且各行非零首元均为1
double a[N][N]//为增广矩阵
int gauss(){
int r, c;// r 表示行 row, c 表示列 col
//枚举列
for(c = 0, r = 0; c < n; c ++){
//找到当前列以下所有行的最大值的行号, 目的:避免系数变得太大,精度较高
int t = r;
for(int i = r; i < n; i ++){
if(fabs(a[i][c]) > fabs(a[t][c])) t = i;
}
//剩余当前列最大行的元素为0,则已满足要求,直接跳过即可
if(fabs(a[t][c]) < eps) continue;//剪枝
//当最大行的元素交换到剩余行的行首
for(int i = c; i <= n; i ++){
if(t == r) continue;
swap(a[r][i], a[t][i]);
}
//处理剩余行首(最大行)的各元素,使得当前列的元素为1
for(int i = n; i >= c; i --){
a[r][i] /= a[r][c];
}
//处理当前列剩余最大行以下的所有元素,使其均为0
for(int i = r + 1; i < n; i ++){
if(fabs(a[i][c]) < eps) continue;//剪枝
for(int j = n; j >= c; j --){
a[i][j] -= a[r][j] * a[i][c];
}
}
r ++;//以保证当前行以上均为上三角行列式,且非零首元均为1, 处理下一行
}
//存在全0行(等号左边全为0)
if(r < n){
for(int i = r; i < n; i ++){
if(fabs(a[i][n]) > eps) return 0;//出现等号左侧为0,右侧不为0的情况,即无解
}
return 2;//有无穷多解
}
//由最后一行倒退至第一行求地未知数的解
for(int i = n - 1; i >= 0; i --){
for(int j = i + 1; j < n; j ++){//i + 1表示当前未知数x后的所有已知解得未知数的起始位置
a[i][n] -= a[i][j] * a[j][n];//用增广矩阵所在列元素存放未知数的值
}
}
return 1;//有唯一解
}
经典例题
高斯消元解线性方程组