Метод Гаусса: различия между версиями
Перейти к навигации
Перейти к поиску
Ctrlalt (обсуждение | вклад) (→Ссылки) |
Ctrlalt (обсуждение | вклад) Нет описания правки |
||
(не показаны 3 промежуточные версии этого же участника) | |||
Строка 17: | Строка 17: | ||
int bestRow = row; | int bestRow = row; | ||
for (int i = row + 1; i < n; i++) | for (int i = row + 1; i < n; i++) | ||
if ( | if (abs(a[i][col]) > abs(a[bestRow][col])) | ||
bestRow = i; | bestRow = i; | ||
if ( | if (abs(a[bestRow][col]) < 1e-9) | ||
continue; | continue; | ||
for (int j = 0; j < m + 1; j++) | for (int j = 0; j < m + 1; j++) | ||
Строка 39: | Строка 39: | ||
for (int col = 0; col < m; col++) | for (int col = 0; col < m; col++) | ||
s += a[row][col] * ans[col]; | s += a[row][col] * ans[col]; | ||
if ( | if (abs(s - a[row][m]) > 1e-9) { | ||
printf("NO"); | printf("NO"); | ||
return 0; | return 0; | ||
Строка 51: | Строка 51: | ||
for (int i = 0; i < m; i++) | for (int i = 0; i < m; i++) | ||
printf("%.10lf ", ans[i]); | printf("%.10lf ", ans[i]); | ||
} | |||
vector<double> gauss(vector<vector<double>> &a) { | |||
int eqCount = a.size(), varCount = a[0].size() - 1; | |||
vector<int> ansRow(varCount, -1); | |||
for (int col = 0, row = 0; col < varCount && row < eqCount; col++) { | |||
int bestRow = row; | |||
for (int i = row + 1; i < eqCount; i++) | |||
if (abs(a[i][col]) > abs(a[bestRow][col])) | |||
bestRow = i; | |||
if (abs(a[bestRow][col]) < 1e-9) | |||
continue; | |||
swap(a[row], a[bestRow]); | |||
ansRow[col] = row; | |||
for (int i = 0; i < eqCount; i++) { | |||
if (i == row) | |||
continue; | |||
double k = -a[i][col] / a[row][col]; | |||
for (int j = col; j <= varCount; j++) | |||
a[i][j] += k * a[row][j]; | |||
} | |||
row++; | |||
} | |||
if (count(ansRow.begin(), ansRow.end(), -1)) | |||
return {}; | |||
vector<double> ans(varCount); | |||
for (int col = 0; col < varCount; col++) | |||
ans[col] = a[ansRow[col]].back() / a[ansRow[col]][col]; | |||
for (int row = 0; row < eqCount; row++) { | |||
double sum = 0; | |||
for (int col = 0; col < varCount; col++) | |||
sum += a[row][col] * ans[col]; | |||
if (abs(sum - a[row].back()) > 1e-9) | |||
return {}; | |||
} | |||
return ans; | |||
} | |||
double getDeterminant(vector<vector<double>> &a) { | |||
double det = 1; | |||
for (int row = 0, col = 0; row < a.size() && col < a.size(); row++, col++) { | |||
int bestRow = row; | |||
for (int i = row + 1; i < a.size(); i++) | |||
if (abs(a[i][col]) > abs(a[bestRow][col])) | |||
bestRow = i; | |||
if (abs(a[bestRow][col]) < 1e-9) | |||
return 0; | |||
swap(a[row], a[bestRow]); | |||
if (row != bestRow) | |||
det *= -1; | |||
det *= a[row][row]; | |||
for (int i = 0; i < a.size(); i++) { | |||
if (i == row) | |||
continue; | |||
double k = -a[i][col] / a[row][col]; | |||
for (int j = col; j < a.size(); j++) | |||
a[i][j] += k * a[row][j]; | |||
} | |||
} | |||
return det; | |||
} | } | ||
== Ссылки == | == Ссылки == | ||
Теория: | Теория: | ||
* [http://e-maxx.ru/algo/linear_systems_gauss e-maxx.ru | * [http://e-maxx.ru/algo/linear_systems_gauss e-maxx.ru — Метод Гаусса решения системы линейных уравнений] | ||
* [http:// | * [http://e-maxx.ru/algo/determinant_gauss e-maxx.ru — Вычисление определителя матрицы методом Гаусса] | ||
Код: | Код: | ||
* [http://github.com/ADJA/algos/blob/master/NumberTheory/Gauss.cpp | * [https://github.com/indy256/codelibrary/blob/master/cpp/linearalgebra/gauss.cpp indy256/codelibrary/cpp/linearalgebra/gauss.cpp] | ||
* [http://github.com/ADJA/algos/blob/master/NumberTheory/Gauss.cpp ADJA/algos/NumberTheory/Gauss.cpp] |
Текущая версия от 19:22, 4 июня 2023
#include <stdio.h> #include <math.h> #include <algorithm> using namespace std; int n, m, ansRow[110]; double a[110][110], ans[110]; int main() { scanf("%d%d", &n, &m); for (int i = 0; i < n; i++) for (int j = 0; j < m + 1; j++) scanf("%lf", &a[i][j]); fill(ansRow, ansRow + m, -1); for (int col = 0, row = 0; col < m && row < n; col++) { int bestRow = row; for (int i = row + 1; i < n; i++) if (abs(a[i][col]) > abs(a[bestRow][col])) bestRow = i; if (abs(a[bestRow][col]) < 1e-9) continue; for (int j = 0; j < m + 1; j++) swap(a[row][j], a[bestRow][j]); ansRow[col] = row; for (int i = 0; i < n; i++) { if (i == row) continue; double k = -a[i][col] / a[row][col]; for (int j = col; j < m + 1; j++) a[i][j] += k * a[row][j]; } row++; } for (int col = 0; col < m; col++) ans[col] = (ansRow[col] != -1 ? a[ansRow[col]][m] / a[ansRow[col]][col] : 0); for (int row = 0; row < n; row++) { double s = 0; for (int col = 0; col < m; col++) s += a[row][col] * ans[col]; if (abs(s - a[row][m]) > 1e-9) { printf("NO"); return 0; } } if (count(ansRow, ansRow + m, -1)) { printf("INF"); return 0; } printf("YES\n"); for (int i = 0; i < m; i++) printf("%.10lf ", ans[i]); }
vector<double> gauss(vector<vector<double>> &a) { int eqCount = a.size(), varCount = a[0].size() - 1; vector<int> ansRow(varCount, -1); for (int col = 0, row = 0; col < varCount && row < eqCount; col++) { int bestRow = row; for (int i = row + 1; i < eqCount; i++) if (abs(a[i][col]) > abs(a[bestRow][col])) bestRow = i; if (abs(a[bestRow][col]) < 1e-9) continue; swap(a[row], a[bestRow]); ansRow[col] = row; for (int i = 0; i < eqCount; i++) { if (i == row) continue; double k = -a[i][col] / a[row][col]; for (int j = col; j <= varCount; j++) a[i][j] += k * a[row][j]; } row++; } if (count(ansRow.begin(), ansRow.end(), -1)) return {}; vector<double> ans(varCount); for (int col = 0; col < varCount; col++) ans[col] = a[ansRow[col]].back() / a[ansRow[col]][col]; for (int row = 0; row < eqCount; row++) { double sum = 0; for (int col = 0; col < varCount; col++) sum += a[row][col] * ans[col]; if (abs(sum - a[row].back()) > 1e-9) return {}; } return ans; }
double getDeterminant(vector<vector<double>> &a) { double det = 1; for (int row = 0, col = 0; row < a.size() && col < a.size(); row++, col++) { int bestRow = row; for (int i = row + 1; i < a.size(); i++) if (abs(a[i][col]) > abs(a[bestRow][col])) bestRow = i; if (abs(a[bestRow][col]) < 1e-9) return 0; swap(a[row], a[bestRow]); if (row != bestRow) det *= -1; det *= a[row][row]; for (int i = 0; i < a.size(); i++) { if (i == row) continue; double k = -a[i][col] / a[row][col]; for (int j = col; j < a.size(); j++) a[i][j] += k * a[row][j]; } } return det; }
Ссылки
Теория:
- e-maxx.ru — Метод Гаусса решения системы линейных уравнений
- e-maxx.ru — Вычисление определителя матрицы методом Гаусса
Код: