#include <iostream>
#include <locale>
#include <cmath>
#include <vector>
#include <algorithm>
#include <iomanip>
#define EPSILON 0.001
using namespace std;
void printVector(const vector<double>& vec) {
for (size_t i = 0; i < vec.size(); ++i) {
wcout << L"x" << (i + 1) << L" = " << fixed << setprecision(10) << vec[i];
if (i < vec.size() - 1) {
wcout << L", ";
}
}
wcout << endl;
}
bool isConvergent(const vector<vector<double>>& matrix) {
int n = matrix.size();
for (int i = 0; i < n; i++) {
double sum = 0;
for (int j = 0; j < n; j++) {
if (i != j) {
sum += abs(matrix[i][j]);
}
}
if (abs(matrix[i][i]) <= sum) {
return false;
}
}
return true;
}
double calculateResidual(const vector<vector<double>>& A, const vector<double>& x, const vector<double>& b) {
double residual = 0.0;
int n = A.size();
for (int i = 0; i < n; ++i) {
double Ax_i = 0.0;
for (int j = 0; j < n; ++j) {
Ax_i += A[i][j] * x[j];
}
residual += pow(Ax_i - b[i], 2);
}
return sqrt(residual);
}
vector<double> gaussSeidel(vector<vector<double>>& A, vector<double>& b, double relaxation, int& iterations) {
if (relaxation == 0.0) {
relaxation = 0.01;
}
int n = A.size();
vector<double> x(n, 0.0);
iterations = 0;
double maxDiff;
do {
maxDiff = 0.0;
for (int i = 0; i < n; i++) {
double sigma = 0.0;
for (int j = 0; j < n; j++) {
if (j != i) {
sigma += A[i][j] * x[j];
}
}
double newValue = (1 - relaxation) * x[i] + relaxation * (b[i] - sigma) / A[i][i];
maxDiff = max(maxDiff, fabs(newValue - x[i]));
x[i] = newValue;
}
iterations++;
} while (maxDiff > EPSILON);
return x;
}
void plotResultsASCII(const vector<double>& relaxation_values, const vector<int>& iteration_counts) {
int maxIterations = *max_element(iteration_counts.begin(), iteration_counts.end());
// Печать заголовка
wcout << L"\nГрафик зависимости числа итераций от параметра релаксации\n";
wcout << L"Параметр релаксации (X) | Итерации (Y)\n";
// Построение графика
for (size_t i = 0; i < relaxation_values.size(); ++i) {
wcout << fixed << setprecision(1) << relaxation_values[i] << L"\t\t| ";
int barLength = static_cast<int>(50.0 * iteration_counts[i] / maxIterations);
for (int j = 0; j < barLength; ++j) {
wcout << L"#";
}
wcout << L" (" << iteration_counts[i] << L")\n";
}
}
int main() {
setlocale(LC_ALL, "Russian");
vector<vector<double>> A = {
{6, 0, 3, -1},
{3, 13, -1, 2},
{5, 7, 15, 1},
{2, 7, -1, 11}
};
vector<double> b = { 16, 8, 85, 52 };
if (!isConvergent(A)) {
wcout << L"Данная матрица не удовлетворяет условиям сходимости." << endl;
return -1;
}
vector<double> relaxation_values;
vector<int> iteration_counts;
for (double relaxation = 0.1; relaxation <= 1.8; relaxation += 0.1) {
int iterations = 0;
vector<double> solution = gaussSeidel(A, b, relaxation, iterations);
relaxation_values.push_back(relaxation);
iteration_counts.push_back(iterations);
if (relaxation == 1.0) {
wcout << L"\nПараметр релаксации: " << relaxation << L", Число итераций: " << iterations << endl;
wcout << L"Решение: ";
printVector(solution);
double residual = calculateResidual(A, solution, b);
wcout << L"Конечная невязка (||Ax - b||): " << residual << endl;
}
}
plotResultsASCII(relaxation_values, iteration_counts);
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8bG9jYWxlPgojaW5jbHVkZSA8Y21hdGg+CiNpbmNsdWRlIDx2ZWN0b3I+CiNpbmNsdWRlIDxhbGdvcml0aG0+CiNpbmNsdWRlIDxpb21hbmlwPgoKI2RlZmluZSBFUFNJTE9OIDAuMDAxCnVzaW5nIG5hbWVzcGFjZSBzdGQ7Cgp2b2lkIHByaW50VmVjdG9yKGNvbnN0IHZlY3Rvcjxkb3VibGU+JiB2ZWMpIHsKICAgIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgdmVjLnNpemUoKTsgKytpKSB7CiAgICAgICAgd2NvdXQgPDwgTCJ4IiA8PCAoaSArIDEpIDw8IEwiID0gIiA8PCBmaXhlZCA8PCBzZXRwcmVjaXNpb24oMTApIDw8IHZlY1tpXTsKICAgICAgICBpZiAoaSA8IHZlYy5zaXplKCkgLSAxKSB7CiAgICAgICAgICAgIHdjb3V0IDw8IEwiLCAiOwogICAgICAgIH0KICAgIH0KICAgIHdjb3V0IDw8IGVuZGw7Cn0KCmJvb2wgaXNDb252ZXJnZW50KGNvbnN0IHZlY3Rvcjx2ZWN0b3I8ZG91YmxlPj4mIG1hdHJpeCkgewogICAgaW50IG4gPSBtYXRyaXguc2l6ZSgpOwogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspIHsKICAgICAgICBkb3VibGUgc3VtID0gMDsKICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IG47IGorKykgewogICAgICAgICAgICBpZiAoaSAhPSBqKSB7CiAgICAgICAgICAgICAgICBzdW0gKz0gYWJzKG1hdHJpeFtpXVtqXSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKGFicyhtYXRyaXhbaV1baV0pIDw9IHN1bSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIHRydWU7Cn0KCmRvdWJsZSBjYWxjdWxhdGVSZXNpZHVhbChjb25zdCB2ZWN0b3I8dmVjdG9yPGRvdWJsZT4+JiBBLCBjb25zdCB2ZWN0b3I8ZG91YmxlPiYgeCwgY29uc3QgdmVjdG9yPGRvdWJsZT4mIGIpIHsKICAgIGRvdWJsZSByZXNpZHVhbCA9IDAuMDsKICAgIGludCBuID0gQS5zaXplKCk7CiAgICBmb3IgKGludCBpID0gMDsgaSA8IG47ICsraSkgewogICAgICAgIGRvdWJsZSBBeF9pID0gMC4wOwogICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgbjsgKytqKSB7CiAgICAgICAgICAgIEF4X2kgKz0gQVtpXVtqXSAqIHhbal07CiAgICAgICAgfQogICAgICAgIHJlc2lkdWFsICs9IHBvdyhBeF9pIC0gYltpXSwgMik7CiAgICB9CiAgICByZXR1cm4gc3FydChyZXNpZHVhbCk7Cn0KCnZlY3Rvcjxkb3VibGU+IGdhdXNzU2VpZGVsKHZlY3Rvcjx2ZWN0b3I8ZG91YmxlPj4mIEEsIHZlY3Rvcjxkb3VibGU+JiBiLCBkb3VibGUgcmVsYXhhdGlvbiwgaW50JiBpdGVyYXRpb25zKSB7CiAgICBpZiAocmVsYXhhdGlvbiA9PSAwLjApIHsKICAgICAgICByZWxheGF0aW9uID0gMC4wMTsKICAgIH0KICAgIGludCBuID0gQS5zaXplKCk7CiAgICB2ZWN0b3I8ZG91YmxlPiB4KG4sIDAuMCk7CiAgICBpdGVyYXRpb25zID0gMDsKCiAgICBkb3VibGUgbWF4RGlmZjsKICAgIGRvIHsKICAgICAgICBtYXhEaWZmID0gMC4wOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKSB7CiAgICAgICAgICAgIGRvdWJsZSBzaWdtYSA9IDAuMDsKICAgICAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBuOyBqKyspIHsKICAgICAgICAgICAgICAgIGlmIChqICE9IGkpIHsKICAgICAgICAgICAgICAgICAgICBzaWdtYSArPSBBW2ldW2pdICogeFtqXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBkb3VibGUgbmV3VmFsdWUgPSAoMSAtIHJlbGF4YXRpb24pICogeFtpXSArIHJlbGF4YXRpb24gKiAoYltpXSAtIHNpZ21hKSAvIEFbaV1baV07CiAgICAgICAgICAgIG1heERpZmYgPSBtYXgobWF4RGlmZiwgZmFicyhuZXdWYWx1ZSAtIHhbaV0pKTsKICAgICAgICAgICAgeFtpXSA9IG5ld1ZhbHVlOwogICAgICAgIH0KICAgICAgICBpdGVyYXRpb25zKys7CiAgICB9IHdoaWxlIChtYXhEaWZmID4gRVBTSUxPTik7CgogICAgcmV0dXJuIHg7Cn0KCnZvaWQgcGxvdFJlc3VsdHNBU0NJSShjb25zdCB2ZWN0b3I8ZG91YmxlPiYgcmVsYXhhdGlvbl92YWx1ZXMsIGNvbnN0IHZlY3RvcjxpbnQ+JiBpdGVyYXRpb25fY291bnRzKSB7CiAgICBpbnQgbWF4SXRlcmF0aW9ucyA9ICptYXhfZWxlbWVudChpdGVyYXRpb25fY291bnRzLmJlZ2luKCksIGl0ZXJhdGlvbl9jb3VudHMuZW5kKCkpOwoKICAgIC8vINCf0LXRh9Cw0YLRjCDQt9Cw0LPQvtC70L7QstC60LAKICAgIHdjb3V0IDw8IEwiXG7Qk9GA0LDRhNC40Log0LfQsNCy0LjRgdC40LzQvtGB0YLQuCDRh9C40YHQu9CwINC40YLQtdGA0LDRhtC40Lkg0L7RgiDQv9Cw0YDQsNC80LXRgtGA0LAg0YDQtdC70LDQutGB0LDRhtC40LhcbiI7CiAgICB3Y291dCA8PCBMItCf0LDRgNCw0LzQtdGC0YAg0YDQtdC70LDQutGB0LDRhtC40LggKFgpIHwg0JjRgtC10YDQsNGG0LjQuCAoWSlcbiI7CgogICAgLy8g0J/QvtGB0YLRgNC+0LXQvdC40LUg0LPRgNCw0YTQuNC60LAKICAgIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgcmVsYXhhdGlvbl92YWx1ZXMuc2l6ZSgpOyArK2kpIHsKICAgICAgICB3Y291dCA8PCBmaXhlZCA8PCBzZXRwcmVjaXNpb24oMSkgPDwgcmVsYXhhdGlvbl92YWx1ZXNbaV0gPDwgTCJcdFx0fCAiOwogICAgICAgIGludCBiYXJMZW5ndGggPSBzdGF0aWNfY2FzdDxpbnQ+KDUwLjAgKiBpdGVyYXRpb25fY291bnRzW2ldIC8gbWF4SXRlcmF0aW9ucyk7CiAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBiYXJMZW5ndGg7ICsraikgewogICAgICAgICAgICB3Y291dCA8PCBMIiMiOwogICAgICAgIH0KICAgICAgICB3Y291dCA8PCBMIiAoIiA8PCBpdGVyYXRpb25fY291bnRzW2ldIDw8IEwiKVxuIjsKICAgIH0KfQoKaW50IG1haW4oKSB7CiAgICBzZXRsb2NhbGUoTENfQUxMLCAiUnVzc2lhbiIpOwogICAgdmVjdG9yPHZlY3Rvcjxkb3VibGU+PiBBID0gewogICAgICAgIHs2LCAwLCAzLCAtMX0sCiAgICAgICAgezMsIDEzLCAtMSwgMn0sCiAgICAgICAgezUsIDcsIDE1LCAxfSwKICAgICAgICB7MiwgNywgLTEsIDExfQogICAgfTsKICAgIHZlY3Rvcjxkb3VibGU+IGIgPSB7IDE2LCA4LCA4NSwgNTIgfTsKCiAgICBpZiAoIWlzQ29udmVyZ2VudChBKSkgewogICAgICAgIHdjb3V0IDw8IEwi0JTQsNC90L3QsNGPINC80LDRgtGA0LjRhtCwINC90LUg0YPQtNC+0LLQu9C10YLQstC+0YDRj9C10YIg0YPRgdC70L7QstC40Y/QvCDRgdGF0L7QtNC40LzQvtGB0YLQuC4iIDw8IGVuZGw7CiAgICAgICAgcmV0dXJuIC0xOwogICAgfQoKICAgIHZlY3Rvcjxkb3VibGU+IHJlbGF4YXRpb25fdmFsdWVzOwogICAgdmVjdG9yPGludD4gaXRlcmF0aW9uX2NvdW50czsKCiAgICBmb3IgKGRvdWJsZSByZWxheGF0aW9uID0gMC4xOyByZWxheGF0aW9uIDw9IDEuODsgcmVsYXhhdGlvbiArPSAwLjEpIHsKICAgICAgICBpbnQgaXRlcmF0aW9ucyA9IDA7CiAgICAgICAgdmVjdG9yPGRvdWJsZT4gc29sdXRpb24gPSBnYXVzc1NlaWRlbChBLCBiLCByZWxheGF0aW9uLCBpdGVyYXRpb25zKTsKCiAgICAgICAgcmVsYXhhdGlvbl92YWx1ZXMucHVzaF9iYWNrKHJlbGF4YXRpb24pOwogICAgICAgIGl0ZXJhdGlvbl9jb3VudHMucHVzaF9iYWNrKGl0ZXJhdGlvbnMpOwoKICAgICAgICBpZiAocmVsYXhhdGlvbiA9PSAxLjApIHsKICAgICAgICAgICAgd2NvdXQgPDwgTCJcbtCf0LDRgNCw0LzQtdGC0YAg0YDQtdC70LDQutGB0LDRhtC40Lg6ICIgPDwgcmVsYXhhdGlvbiA8PCBMIiwg0KfQuNGB0LvQviDQuNGC0LXRgNCw0YbQuNC5OiAiIDw8IGl0ZXJhdGlvbnMgPDwgZW5kbDsKICAgICAgICAgICAgd2NvdXQgPDwgTCLQoNC10YjQtdC90LjQtTogIjsKICAgICAgICAgICAgcHJpbnRWZWN0b3Ioc29sdXRpb24pOwogICAgICAgICAgICBkb3VibGUgcmVzaWR1YWwgPSBjYWxjdWxhdGVSZXNpZHVhbChBLCBzb2x1dGlvbiwgYik7CiAgICAgICAgICAgIHdjb3V0IDw8IEwi0JrQvtC90LXRh9C90LDRjyDQvdC10LLRj9C30LrQsCAofHxBeCAtIGJ8fCk6ICIgPDwgcmVzaWR1YWwgPDwgZW5kbDsKICAgICAgICB9CiAgICB9CgogICAgcGxvdFJlc3VsdHNBU0NJSShyZWxheGF0aW9uX3ZhbHVlcywgaXRlcmF0aW9uX2NvdW50cyk7CgogICAgcmV0dXJuIDA7Cn0K