#include <iostream>
#include <locale>
#include <cmath>
#include <vector>
#include <algorithm>
#include <fstream>
#include <iomanip>
#include <cstdlib> // Для вызова system()
#define EPSILON 0.001
using namespace std;
void printVector(const std::vector<double>& vec) {
for (size_t i = 0; i < vec.size(); ++i) {
std::wcout << L"x" << (i + 1) << L" = " << std::fixed << std::setprecision(10) << vec[i];
if (i < vec.size() - 1) {
std::wcout << L", ";
}
}
std::wcout << std::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) {
// При релаксации = 0 решаем стандартным методом Гаусса-Зейделя
relaxation = 0.01;
}
int n = A.size();
vector<double> x(n, 0.0); // Начальное приближение устанавливаем в 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 plotResults(const vector<double>& relaxation_values, const vector<int>& iteration_counts) {
ofstream dataFile("data.dat");
for (size_t i = 0; i < relaxation_values.size(); ++i) {
dataFile << relaxation_values[i] << " " << iteration_counts[i] << "\n";
}
dataFile.close();
}
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;
}
int k = 0;
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);
if (relaxation >= 0.9 && k == 0) {
wcout << fixed << L"Параметр релаксации: " << relaxation << L", Число итераций: " << iterations << endl;
wcout << L"Решение: ";
wcout.precision(10);
printVector(solution);
// Вычисляем и выводим конечную невязку
double residual = calculateResidual(A, solution, b);
wcout << L"Конечная невязка (||Ax - b||): " << residual << endl;
k = 1;
}
// Сохраняем результаты для построения графика
relaxation_values.push_back(relaxation);
iteration_counts.push_back(iterations);
}
// Построение графика с помощью Gnuplot
plotResults(relaxation_values, iteration_counts);
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPiAKI2luY2x1ZGUgPGxvY2FsZT4KI2luY2x1ZGUgPGNtYXRoPgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8YWxnb3JpdGhtPgojaW5jbHVkZSA8ZnN0cmVhbT4KI2luY2x1ZGUgPGlvbWFuaXA+CiNpbmNsdWRlIDxjc3RkbGliPiAvLyDQlNC70Y8g0LLRi9C30L7QstCwIHN5c3RlbSgpCgojZGVmaW5lIEVQU0lMT04gMC4wMDEKCnVzaW5nIG5hbWVzcGFjZSBzdGQ7Cgp2b2lkIHByaW50VmVjdG9yKGNvbnN0IHN0ZDo6dmVjdG9yPGRvdWJsZT4mIHZlYykgewogICAgZm9yIChzaXplX3QgaSA9IDA7IGkgPCB2ZWMuc2l6ZSgpOyArK2kpIHsKICAgICAgICBzdGQ6Ondjb3V0IDw8IEwieCIgPDwgKGkgKyAxKSA8PCBMIiA9ICIgPDwgc3RkOjpmaXhlZCA8PCBzdGQ6OnNldHByZWNpc2lvbigxMCkgPDwgdmVjW2ldOwogICAgICAgIGlmIChpIDwgdmVjLnNpemUoKSAtIDEpIHsKICAgICAgICAgICAgc3RkOjp3Y291dCA8PCBMIiwgIjsKICAgICAgICB9CiAgICB9CiAgICBzdGQ6Ondjb3V0IDw8IHN0ZDo6ZW5kbDsKfQoKYm9vbCBpc0NvbnZlcmdlbnQoY29uc3QgdmVjdG9yPHZlY3Rvcjxkb3VibGU+PiYgbWF0cml4KSB7CiAgICAvLyDQn9GA0L7QstC10YDRj9C10LwsINGD0LTQvtCy0LvQtdGC0LLQvtGA0Y/QtdGCINC70Lgg0LzQsNGC0YDQuNGG0LAg0YPRgdC70L7QstC40Y4g0LTQuNCw0LPQvtC90LDQu9GM0L3QvtCz0L4g0L/RgNC10L7QsdC70LDQtNCw0L3QuNGPINC00LvRjyDRgdGF0L7QtNC40LzQvtGB0YLQuC4KICAgIGludCBuID0gbWF0cml4LnNpemUoKTsKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKSB7CiAgICAgICAgZG91YmxlIHN1bSA9IDA7CiAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBuOyBqKyspIHsKICAgICAgICAgICAgaWYgKGkgIT0gaikgewogICAgICAgICAgICAgICAgc3VtICs9IGFicyhtYXRyaXhbaV1bal0pOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmIChhYnMobWF0cml4W2ldW2ldKSA8PSBzdW0pIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiB0cnVlOwp9Cgpkb3VibGUgY2FsY3VsYXRlUmVzaWR1YWwoY29uc3QgdmVjdG9yPHZlY3Rvcjxkb3VibGU+PiYgQSwgY29uc3QgdmVjdG9yPGRvdWJsZT4mIHgsIGNvbnN0IHZlY3Rvcjxkb3VibGU+JiBiKSB7CiAgICBkb3VibGUgcmVzaWR1YWwgPSAwLjA7CiAgICBpbnQgbiA9IEEuc2l6ZSgpOwogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyArK2kpIHsKICAgICAgICBkb3VibGUgQXhfaSA9IDAuMDsKICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IG47ICsraikgewogICAgICAgICAgICBBeF9pICs9IEFbaV1bal0gKiB4W2pdOwogICAgICAgIH0KICAgICAgICByZXNpZHVhbCArPSBwb3coQXhfaSAtIGJbaV0sIDIpOwogICAgfQogICAgcmV0dXJuIHNxcnQocmVzaWR1YWwpOwp9Cgp2ZWN0b3I8ZG91YmxlPiBnYXVzc1NlaWRlbCh2ZWN0b3I8dmVjdG9yPGRvdWJsZT4+JiBBLCB2ZWN0b3I8ZG91YmxlPiYgYiwgZG91YmxlIHJlbGF4YXRpb24sIGludCYgaXRlcmF0aW9ucykgewogICAgaWYgKHJlbGF4YXRpb24gPT0gMC4wKSB7CiAgICAgICAgLy8g0J/RgNC4INGA0LXQu9Cw0LrRgdCw0YbQuNC4ID0gMCDRgNC10YjQsNC10Lwg0YHRgtCw0L3QtNCw0YDRgtC90YvQvCDQvNC10YLQvtC00L7QvCDQk9Cw0YPRgdGB0LAt0JfQtdC50LTQtdC70Y8KICAgICAgICByZWxheGF0aW9uID0gMC4wMTsKICAgIH0KICAgIGludCBuID0gQS5zaXplKCk7CiAgICB2ZWN0b3I8ZG91YmxlPiB4KG4sIDAuMCk7IC8vINCd0LDRh9Cw0LvRjNC90L7QtSDQv9GA0LjQsdC70LjQttC10L3QuNC1INGD0YHRgtCw0L3QsNCy0LvQuNCy0LDQtdC8INCyIDAuMAogICAgaXRlcmF0aW9ucyA9IDA7CgogICAgZG91YmxlIG1heERpZmY7CiAgICBkbyB7CiAgICAgICAgbWF4RGlmZiA9IDAuMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykgewogICAgICAgICAgICBkb3VibGUgc2lnbWEgPSAwLjA7CiAgICAgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgbjsgaisrKSB7CiAgICAgICAgICAgICAgICBpZiAoaiAhPSBpKSB7CiAgICAgICAgICAgICAgICAgICAgc2lnbWEgKz0gQVtpXVtqXSAqIHhbal07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZG91YmxlIG5ld1ZhbHVlID0gKDEgLSByZWxheGF0aW9uKSAqIHhbaV0gKyByZWxheGF0aW9uICogKGJbaV0gLSBzaWdtYSkgLyBBW2ldW2ldOwogICAgICAgICAgICBtYXhEaWZmID0gbWF4KG1heERpZmYsIGZhYnMobmV3VmFsdWUgLSB4W2ldKSk7CiAgICAgICAgICAgIHhbaV0gPSBuZXdWYWx1ZTsKICAgICAgICB9CiAgICAgICAgaXRlcmF0aW9ucysrOwogICAgfSB3aGlsZSAobWF4RGlmZiA+IEVQU0lMT04pOyAvLyDQntCz0YDQsNC90LjRh9C10L3QuNC1INC90LAg0LrQvtC70LjRh9C10YHRgtCy0L4g0LjRgtC10YDQsNGG0LjQuQoKICAgIHJldHVybiB4Owp9Cgp2b2lkIHBsb3RSZXN1bHRzKGNvbnN0IHZlY3Rvcjxkb3VibGU+JiByZWxheGF0aW9uX3ZhbHVlcywgY29uc3QgdmVjdG9yPGludD4mIGl0ZXJhdGlvbl9jb3VudHMpIHsKICAgIG9mc3RyZWFtIGRhdGFGaWxlKCJkYXRhLmRhdCIpOwogICAgZm9yIChzaXplX3QgaSA9IDA7IGkgPCByZWxheGF0aW9uX3ZhbHVlcy5zaXplKCk7ICsraSkgewogICAgICAgIGRhdGFGaWxlIDw8IHJlbGF4YXRpb25fdmFsdWVzW2ldIDw8ICIgIiA8PCBpdGVyYXRpb25fY291bnRzW2ldIDw8ICJcbiI7CiAgICB9CiAgICBkYXRhRmlsZS5jbG9zZSgpOwoKCn0KCmludCBtYWluKCkgewogICAgc2V0bG9jYWxlKExDX0FMTCwgIlJ1c3NpYW4iKTsKICAgIHZlY3Rvcjx2ZWN0b3I8ZG91YmxlPj4gQSA9IHsKICAgICAgICB7NiwgMCwgMywgLTF9LAogICAgICAgIHszLCAxMywgLTEsIDJ9LAogICAgICAgIHs1LCA3LCAxNSwgMX0sCiAgICAgICAgezIsIDcsIC0xLCAxMX0KICAgIH07CiAgICB2ZWN0b3I8ZG91YmxlPiBiID0geyAxNiwgOCwgODUsIDUyIH07CgogICAgaWYgKCFpc0NvbnZlcmdlbnQoQSkpIHsKICAgICAgICB3Y291dCA8PCBMItCU0LDQvdC90LDRjyDQvNCw0YLRgNC40YbQsCDQvdC1INGD0LTQvtCy0LvQtdGC0LLQvtGA0Y/QtdGCINGD0YHQu9C+0LLQuNGP0Lwg0YHRhdC+0LTQuNC80L7RgdGC0LguIiA8PCBlbmRsOwogICAgICAgIHJldHVybiAtMTsKICAgIH0KICAgIGludCBrID0gMDsKICAgIHZlY3Rvcjxkb3VibGU+IHJlbGF4YXRpb25fdmFsdWVzOwogICAgdmVjdG9yPGludD4gaXRlcmF0aW9uX2NvdW50czsKICAgIGZvciAoZG91YmxlIHJlbGF4YXRpb24gPSAwLjE7IHJlbGF4YXRpb24gPD0gMS44OyByZWxheGF0aW9uICs9IDAuMSkgewogICAgICAgIGludCBpdGVyYXRpb25zID0gMDsKCiAgICAgICAgdmVjdG9yPGRvdWJsZT4gc29sdXRpb24gPSBnYXVzc1NlaWRlbChBLCBiLCByZWxheGF0aW9uLCBpdGVyYXRpb25zKTsKICAgICAgICBpZiAocmVsYXhhdGlvbiA+PSAwLjkgJiYgayA9PSAwKSB7CiAgICAgICAgICAgIHdjb3V0IDw8IGZpeGVkIDw8IEwi0J/QsNGA0LDQvNC10YLRgCDRgNC10LvQsNC60YHQsNGG0LjQuDogIiA8PCByZWxheGF0aW9uIDw8IEwiLCDQp9C40YHQu9C+INC40YLQtdGA0LDRhtC40Lk6ICIgPDwgaXRlcmF0aW9ucyA8PCBlbmRsOwogICAgICAgICAgICB3Y291dCA8PCBMItCg0LXRiNC10L3QuNC1OiAiOwogICAgICAgICAgICB3Y291dC5wcmVjaXNpb24oMTApOwogICAgICAgICAgICBwcmludFZlY3Rvcihzb2x1dGlvbik7CiAgICAgICAgICAgIC8vINCS0YvRh9C40YHQu9GP0LXQvCDQuCDQstGL0LLQvtC00LjQvCDQutC+0L3QtdGH0L3Rg9GOINC90LXQstGP0LfQutGDCiAgICAgICAgICAgIGRvdWJsZSByZXNpZHVhbCA9IGNhbGN1bGF0ZVJlc2lkdWFsKEEsIHNvbHV0aW9uLCBiKTsKICAgICAgICAgICAgd2NvdXQgPDwgTCLQmtC+0L3QtdGH0L3QsNGPINC90LXQstGP0LfQutCwICh8fEF4IC0gYnx8KTogIiA8PCByZXNpZHVhbCA8PCBlbmRsOwogICAgICAgICAgICBrID0gMTsKCiAgICAgICAgfQoKCgogICAgICAgIC8vINCh0L7RhdGA0LDQvdGP0LXQvCDRgNC10LfRg9C70YzRgtCw0YLRiyDQtNC70Y8g0L/QvtGB0YLRgNC+0LXQvdC40Y8g0LPRgNCw0YTQuNC60LAKICAgICAgICByZWxheGF0aW9uX3ZhbHVlcy5wdXNoX2JhY2socmVsYXhhdGlvbik7CiAgICAgICAgaXRlcmF0aW9uX2NvdW50cy5wdXNoX2JhY2soaXRlcmF0aW9ucyk7CiAgICB9CgoKCiAgICAvLyDQn9C+0YHRgtGA0L7QtdC90LjQtSDQs9GA0LDRhNC40LrQsCDRgSDQv9C+0LzQvtGJ0YzRjiBHbnVwbG90CiAgICBwbG90UmVzdWx0cyhyZWxheGF0aW9uX3ZhbHVlcywgaXRlcmF0aW9uX2NvdW50cyk7CgogICAgcmV0dXJuIDA7Cn0K