一、列主元消去法:
在第k步消元前,先找出 k 行下所有第k列元素最大的非零元素
![\large a_{r,k}](https://i-blog.csdnimg.cn/blog_migrate/77f9231bffb9f748c83aee49fedab4cb.gif)
,将第r行与第k行进行整行交换,这样既不影响原方程的解,也可以将绝对值最大的
![\large a_{r,k}](https://i-blog.csdnimg.cn/blog_migrate/77f9231bffb9f748c83aee49fedab4cb.gif)
作为主元,放在除数的位置上,尽可能减小引入误差。变为上三角矩阵后 从下往上求出 Xi
以代码中的测试矩阵为例给出运行的过程:
{0, 0, 0, 0, 0},
{0, 2, 1, -1, 8},
{0, -3, -1, 2, -11},
{0, -2, 1, 2, -3}
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 5;
double a[4][MAXN] = {
{0, 0, 0, 0, 0},
{0, 2, 1, -1, 8},
{0, -3, -1, 2, -11},
{0, -2, 1, 2, -3}
};
//输出矩阵
void printM(int n) {
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n + 1; j++)
printf("%10f,", a[i][j]);
printf("\n");
}
}
//选择列主元并进行消元
void SelectColE(int n) {
double temp; //用于记录消元时的因数
for (int i = 1; i <= n; i++) {
int r = i;
for (int j = i + 1; j <= n; j++)
if (fabs(a[j][i]) > fabs(a[r][i]))
r = j;
if (r != i)
{
printf("%d %d行换\n", i, r);
printM(3);
printf("--------------------------\n");
for (int j = i; j <= n + 1; j++)
swap(a[i][j], a[r][j]);//与最大主元所在行交换
printM(3);
}
if (fabs(a[i][i]) < 1e-7)//绝对值最大的元素为0 矩阵没有唯一解
{
cout << "NO answer!\n";
exit(0);
}
for (int j = i + 1; j <= n; j++) {//消元
temp = a[j][i] / a[i][i];
for (int k = i; k <= n + 1; k++)
a[j][k] -= a[i][k] * temp;
}
printf("第%d列消元后:\n", i);
printM(3);
printf("--------------------------\n");
}
}
//高斯消元法(列选主元)
void Gauss(int n) {
SelectColE(n);//列选主元并消元成上三角
printf("上三角的结果:\n");
printM(3);
for (int i = n; i >= 1; i--) {//回代求解
for (int j = i + 1; j <= n; j++)
a[i][n + 1] -= a[i][j] * a[j][n + 1];
a[i][n + 1] /= a[i][i];
}
}
//测试函数
int main() {
Gauss(3);
for (int i = 1; i <= 3; i++)
printf("X%d = %9f\n", i, a[i][4]);
return 0;
}