高斯若尔当消元法
算法内容:
该算法主要用于求解线性方程组的解,其原理是,将增广矩阵化成行最简形矩阵,最终能求出方程是否有解、有解时自由元的个数和非自由元的解。
/// /// _ooOoo_ /// o8888888o /// 88" . "88 /// (| -_- |) /// O\ = /O /// ____/`---'\____ /// .' \\| |// `. /// / \\||| : |||// \ /// / _||||| -:- |||||- \ /// | | \\\ - /// | | /// | \_| ''\---/'' | | /// \ .-\__ `-` ___/-. / /// ___`. .' /--.--\ `. . __ /// ."" '< `.___\_<|>_/___.' >'"". /// | | : `- \`.;`\ _ /`;.`/ - ` : | | /// \ \ `-. \_ __\ /__ _/ .-` / / /// ======`-.____`-.___\_____/___.-`____.-'====== /// `=---=' /// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /// Buddha Bless, No Bug ! /// #include <iostream> #include <string> #include <cmath> #include <cstdio> #include <cstdlib> #define eps 1e-9 using namespace std; const int MAXN = 220; double a[MAXN][MAXN], x[MAXN];///方程左边的矩阵和等于等式右边的值,求解之后X存的就是结果 int equ, var;///(方程数)和(未知数个数) /* 返回-1表示一个解,0表示无解,其余的数表示有K个自由元 */ int Gauss() { int i, j, k, col, max_r; for (k = 0, col = 0; k < equ && col < var; k++, col++) { max_r = k; for (i = k + 1; i < equ; i++)///逐层寻找绝对值比第(k, k)个数大的数,便于后面化成行最简型 { if (fabs(a[i][col]) > fabs(a[max_r][col]))///逐层寻找绝对值比第(k, k)个数大的数,便于后面化成行最简型 { max_r = i; } } if (abs(a[max_r][col]) < eps) { continue; } if (k != max_r)///如果最大的数所在行不与K同行,就进行交换,方便后面的行减去他,然后转换成行最简型 { for (j = col; j < var; j++)///进行交换 { swap(a[k][j], a[max_r][j]); } swap(x[k], x[max_r]); } x[k] /= a[k][col]; for (j = col + 1; j < var; j++)///使(k,col)元素在k行以后的元素都除以他,而他自己变成1 { a[k][j] /= a[k][col];///使a[k][col] = 1,使这行逐渐变成行最简形矩阵 } a[k][col] = 1; for (i = 0; i < equ; i++) { if (i != k) { x[i] -= x[k] * a[i][k];///x[i] 减去 (第k行的x[k]与a[i][k]的乘积),与后面的a[i][j] -= a[k][j] * a[i][col]合在一起就是每一行减去第K行 for (j = col + 1; j < var; j++) { a[i][j] -= a[k][j] * a[i][col];///使(其他所有行)减去(第k行) } a[i][col] = 0; } } } for (i = equ - 1; i >= 0; i--)/// { bool bul = 1; for (j = var - 1; j >= 0; j--) { if (abs(a[i][j]) > eps)///如果有解(R(a) = R(a, x)) { bul = 0; } } if (bul && abs(x[i]) > eps)///如果无解(R(a)<R(a, x)) { return 0; } } int free_num = var; for (i = equ - 1; i >= 0; i--)/// { for (j = var - 1; j >= 0; j--) { if (abs(a[i][j]) > eps) { free_num--;///计算自由元个数 break; } } } if (free_num == 0) { return -1; } return var - free_num; } int main() { int n, m; while (scanf("%d%d", &equ, &var) != EOF) { for (int i = 0; i < equ; i++) { for (int j = 0; j < var; j++) { cin >> a[i][j]; } cin >> x[i];///存的是方程的结果,也就是增广矩阵的b[] a[i][var] = i + 1;///存这个行的序号 } cout << Gauss() << endl; for (int i = 0; i < equ; i++) { for (int j = 0; j < var; j++) { printf("%5.2f ", a[i][j]);///输出矩阵变换后的每个数 } cout << endl; } for (int i = 0; i < var; i++) { printf("%d : %.2f\n", i + 1, x[i]);///x[i]此时存的是未知数的解 } } return 0; }