详解高斯消元
__mt19937__ · · 算法·理论
详解高斯消元
前置知识
一般消元法的公理:
-
两方程互换,解不变;
-
一方程乘以非零数
k ,解不变; -
一方程乘以数
k 加上另一方程,解不变。
增广矩阵:
由一个矩阵
通常为一下格式:
高斯消元的目标矩阵
即上三角矩阵:
基本步骤
1.转化
把方程组转化为一下格式:
2.把系数写成增广矩阵
依据:
-
在消元法中,参与计算和发生改变的是方程中各变量的系数;
-
各变量并未参与计算,且没有发生改变;
-
可以利用系数的位置表示变量,从而省略变量;
-
在计算中将变量简化省略,方程的解不变。
3.行变换消元
第
如果主元为
然后,将第
再将第
4.回带
傻子都会。
CODE
#include <cmath>
#include <cstdio>
#include <utility>
using namespace std;
const long double eps = 0.0000000000001L;
long double mat[101][102];
bool isZero(long double x)
{
return fabs(x) < eps;
}
bool solve(int n)
{
for (int i = 1; i <= n; i++)
{
int notZero = i;
for (int j = i; j <= n; j++)
{
if (!isZero(mat[j][i]))
{
notZero = j;
break;
}
}
if (notZero != i)
{
swap(mat[i], mat[notZero]);
}
if (isZero(mat[i][i]))
{
return false;
}
for (int j = i + 1; j <= n + 1; j++)
{
mat[i][j] /= mat[i][i];
}
for (int j = i + 1; j <= n; j++)
{
for (int k = i + 1; k <= n + 1; k++)
{
mat[j][k] -= mat[j][i] * mat[i][k];
}
}
}
for (int i = n - 1; i >= 1; i--)
{
for (int j = i + 1; j <= n; j++)
{
mat[i][n + 1] -= mat[i][j] * mat[j][n + 1];
}
}
return true;
}
int main()
{
int n;
scanf("%d", &n);
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n + 1; j++)
{
scanf("%Lf", &mat[i][j]);
}
}
if (solve(n))
{
for (int i = 1; i <= n; i++)
{
printf("%.2Lf\n", mat[i][n + 1]);
}
}
else
{
puts("No Solution");
}
return 0;
}