fork download
  1. #include <iostream>
  2. #include <locale>
  3. #include <cmath>
  4. #include <vector>
  5. #include <algorithm>
  6. #include <iomanip>
  7.  
  8. #define EPSILON 0.001
  9. using namespace std;
  10.  
  11. void printVector(const vector<double>& vec) {
  12. for (size_t i = 0; i < vec.size(); ++i) {
  13. wcout << L"x" << (i + 1) << L" = " << fixed << setprecision(10) << vec[i];
  14. if (i < vec.size() - 1) {
  15. wcout << L", ";
  16. }
  17. }
  18. wcout << endl;
  19. }
  20.  
  21. bool isConvergent(const vector<vector<double>>& matrix) {
  22. int n = matrix.size();
  23. for (int i = 0; i < n; i++) {
  24. double sum = 0;
  25. for (int j = 0; j < n; j++) {
  26. if (i != j) {
  27. sum += abs(matrix[i][j]);
  28. }
  29. }
  30. if (abs(matrix[i][i]) <= sum) {
  31. return false;
  32. }
  33. }
  34. return true;
  35. }
  36.  
  37. double calculateResidual(const vector<vector<double>>& A, const vector<double>& x, const vector<double>& b) {
  38. double residual = 0.0;
  39. int n = A.size();
  40. for (int i = 0; i < n; ++i) {
  41. double Ax_i = 0.0;
  42. for (int j = 0; j < n; ++j) {
  43. Ax_i += A[i][j] * x[j];
  44. }
  45. residual += pow(Ax_i - b[i], 2);
  46. }
  47. return sqrt(residual);
  48. }
  49.  
  50. vector<double> gaussSeidel(vector<vector<double>>& A, vector<double>& b, double relaxation, int& iterations) {
  51. if (relaxation == 0.0) {
  52. relaxation = 0.01;
  53. }
  54. int n = A.size();
  55. vector<double> x(n, 0.0);
  56. iterations = 0;
  57.  
  58. double maxDiff;
  59. do {
  60. maxDiff = 0.0;
  61. for (int i = 0; i < n; i++) {
  62. double sigma = 0.0;
  63. for (int j = 0; j < n; j++) {
  64. if (j != i) {
  65. sigma += A[i][j] * x[j];
  66. }
  67. }
  68. double newValue = (1 - relaxation) * x[i] + relaxation * (b[i] - sigma) / A[i][i];
  69. maxDiff = max(maxDiff, fabs(newValue - x[i]));
  70. x[i] = newValue;
  71. }
  72. iterations++;
  73. } while (maxDiff > EPSILON);
  74.  
  75. return x;
  76. }
  77.  
  78. void plotResultsASCII(const vector<double>& relaxation_values, const vector<int>& iteration_counts) {
  79. int maxIterations = *max_element(iteration_counts.begin(), iteration_counts.end());
  80.  
  81. // Печать заголовка
  82. wcout << L"\nГрафик зависимости числа итераций от параметра релаксации\n";
  83. wcout << L"Параметр релаксации (X) | Итерации (Y)\n";
  84.  
  85. // Построение графика
  86. for (size_t i = 0; i < relaxation_values.size(); ++i) {
  87. wcout << fixed << setprecision(1) << relaxation_values[i] << L"\t\t| ";
  88. int barLength = static_cast<int>(50.0 * iteration_counts[i] / maxIterations);
  89. for (int j = 0; j < barLength; ++j) {
  90. wcout << L"#";
  91. }
  92. wcout << L" (" << iteration_counts[i] << L")\n";
  93. }
  94. }
  95.  
  96. int main() {
  97. setlocale(LC_ALL, "Russian");
  98. vector<vector<double>> A = {
  99. {6, 0, 3, -1},
  100. {3, 13, -1, 2},
  101. {5, 7, 15, 1},
  102. {2, 7, -1, 11}
  103. };
  104. vector<double> b = { 16, 8, 85, 52 };
  105.  
  106. if (!isConvergent(A)) {
  107. wcout << L"Данная матрица не удовлетворяет условиям сходимости." << endl;
  108. return -1;
  109. }
  110.  
  111. vector<double> relaxation_values;
  112. vector<int> iteration_counts;
  113.  
  114. for (double relaxation = 0.1; relaxation <= 1.8; relaxation += 0.1) {
  115. int iterations = 0;
  116. vector<double> solution = gaussSeidel(A, b, relaxation, iterations);
  117.  
  118. relaxation_values.push_back(relaxation);
  119. iteration_counts.push_back(iterations);
  120.  
  121. if (relaxation == 1.0) {
  122. wcout << L"\nПараметр релаксации: " << relaxation << L", Число итераций: " << iterations << endl;
  123. wcout << L"Решение: ";
  124. printVector(solution);
  125. double residual = calculateResidual(A, solution, b);
  126. wcout << L"Конечная невязка (||Ax - b||): " << residual << endl;
  127. }
  128. }
  129.  
  130. plotResultsASCII(relaxation_values, iteration_counts);
  131.  
  132. return 0;
  133. }
  134.  
Success #stdin #stdout 0.01s 5284KB
stdin
Standard input is empty
stdout
?????? ??????????? ????? ???????? ?? ????????? ??????????
???????? ?????????? (X) | ???????? (Y)
0.1		| ################################################## (71)
0.2		| ########################## (38)
0.3		| ################## (26)
0.4		| ############## (20)
0.5		| ########### (16)
0.6		| ######### (13)
0.7		| ####### (10)
0.8		| ###### (9)
0.9		| #### (7)
1.0		| ### (5)
1.1		| #### (6)
1.2		| #### (7)
1.3		| ###### (9)
1.4		| ######### (13)
1.5		| ########### (17)
1.6		| ################## (26)
1.7		| ########################### (39)