00:00:00
高斯消元 笔记
一、高斯消元
如果有以下方程组,可以用这样的方法求解:
把它的系数提出来,得到以下矩阵:
基本思路是:通过更换各个方程的位置,并用加减消元法使得
看不懂上面的式子看下面的例子,可以看出从下往上一直代入即可解出所有解:
再说解这个方程:
- 从
式往下找,找到第一个有系数的 ,并交换到 式的位置。
- 将
式乘上 得到 式(下面未给出),即 ,在令 式等于 式减 式:
- 对接下来每个
和 式做相同操作:
- 解出
,代入 式,解出 ,将全部代入 式,解出 。
高斯消元就是对这个矩阵进行如上操作,发现上面操作可以非常机械化的解方程,易于程序实现。
cpp
const double eps = 1e-7; // 绝对值小于 10^(-7) 的数我们就当它是 0 了
void gauss() {
for (int i = 1; i <= n; i++) {
int p = 0;
for (int j = i; j <= n; j++)
if (abs(a[j][i]) > eps) {
p = j;
break;
}
if (!p) {
cout << "No Solution";
return;
}
swap(a[i], a[p]);
for (int j = i + 1; j <= n; j++) {
double x = a[j][i] / a[i][i];
for (int k = i; k <= n + 1; k++)
a[j][k] -= a[i][k] * x;
}
}
for (int i = n; i; i--) {
a[i][i] = a[i][n + 1] / a[i][i];
for (int j = i - 1; j; j--) {
a[j][n + 1] -= a[j][i] * a[i][i];
a[j][i] = 0;
}
}
for (int i = 1; i <= n; i++)
cout << fixed << setprecision(2) << a[i][i] << "\n";
}无穷多个解:出现
无解:出现
二、高斯-约旦消元
无需回带,直接把每一行都用加减消元消到只剩
找最大的系数来作为被减式是为了减少误差。
cpp
void gauss() {
for (int i = 1; i <= n; i++) {
int p = i;
for (int j = 1; j <= n; j++) {
if (abs(a[j][j]) > eps and j < i)
continue;
if (abs(a[j][i]) > abs(a[p][i]))
p = j;
}
swap(a[i], a[p]);
if (abs(a[i][i]) <= eps) continue;
for (int j = 1; j <= n; j++) {
if (i == j) continue;
double x = a[j][i] / a[i][i];
for (int k = i; k <= n + 1; k++)
a[j][k] -= a[i][k] * x;
}
}
}如果出现
如果出现