3 / 1302_3_3
.pdfint N = 2;
vector<vector<double>> A = {{4.0, 1.0}, {1.0, 3.0}}; vector<double> b = {5.0, 4.0};
vector<double> x = {0.0, 0.0};
int w_iter = 10; int w_val = 15;
int total_w = w_iter + w_val + w_val;
cout << left << setw(w_iter) << "Iter" << setw(w_val) << "x1" << setw(w_val) << "x2" << endl;
cout << string(total_w, '-') << endl;
for (int iter = 1; iter <= MANUAL_ITERS; iter++) { double sum1 = A[0][1] * x[1];
x[0] = (b[0] - sum1) / A[0][0];
double sum2 = A[1][0] * x[0]; x[1] = (b[1] - sum2) / A[1][1];
cout << left << setw(w_iter) << iter
<<setw(w_val) << x[0]
<<setw(w_val) << x[1] << endl;
}
cout << string(total_w, '=') << endl; cout << endl;
}
// Генерация СЛАУ и расчёты
void generateSystem(int N, vector<vector<double>>& A, vector<double>& b) { A.resize(N, vector<double>(N));
b.resize(N);
vector<double> x_exact(N, 1.0);
11
unsigned int time_seed = (unsigned int)time(NULL);
#pragma omp parallel for for (int i = 0; i < N; i++) { double row_sum = 0;
unsigned int seed = i + time_seed; for (int j = 0; j < N; j++) {
if (i != j) {
A[i][j] = (rand_r(&seed) % 10 + 1) * 0.01; row_sum += abs(A[i][j]);
}
}
A[i][i] = row_sum + (rand_r(&seed) % 10 + 1.0);
}
#pragma omp parallel for for (int i = 0; i < N; i++) {
b[i] = 0;
for (int j = 0; j < N; j++) { b[i] += A[i][j] * x_exact[j];
}
}
}
double runSequential(int N, const vector<vector<double>>& A, const vector<double>& b) { vector<double> x(N, 0.0);
auto start = chrono::high_resolution_clock::now();
for (int iter = 0; iter < MAX_ITER; iter++) { double max_error = 0.0;
for (int i = 0; i < N; i++) { double old_xi = x[i];
12
double sum = 0.0;
for (int j = 0; j < N; j++) {
if (i != j) sum += A[i][j] * x[j];
}
x[i] = (b[i] - sum) / A[i][i];
max_error = max(max_error, abs(x[i] - old_xi));
}
if (max_error < EPSILON) break;
}
auto end = chrono::high_resolution_clock::now();
return chrono::duration<double, milli>(end - start).count();
}
double runParallel(int N, const vector<vector<double>>& A, const vector<double>& b, int threads) {
vector<double> x(N, 0.0); omp_set_num_threads(threads);
auto start = chrono::high_resolution_clock::now();
for (int iter = 0; iter < MAX_ITER; iter++) { double max_error = 0.0;
#pragma omp parallel for reduction(max:max_error) for (int i = 0; i < N; i++) {
double old_xi = x[i]; double sum = 0.0;
for (int j = 0; j < N; j++) {
if (i != j) sum += A[i][j] * x[j];
}
x[i] = (b[i] - sum) / A[i][i];
double current_error = abs(x[i] - old_xi);
if (current_error > max_error) max_error = current_error;
}
if (max_error < EPSILON) break;
}
13
auto end = chrono::high_resolution_clock::now();
return chrono::duration<double, milli>(end - start).count();
}
// Вывод таблицы
void printDoubleLine(int num_cols) { cout << string(W_LABEL + 1, '=');
for(int i=0; i<num_cols; i++) cout << "+" << string(W_DATA + 1, '='); cout << "|" << endl;
}
void printSeparatorLine(int num_cols) { cout << string(W_LABEL + 1, '-');
for(int i=0; i<num_cols; i++) cout << "+" << string(W_DATA + 1, '-'); cout << "|" << endl;
}
int main() { srand(time(NULL));
runExample();
int total_configs = 1 + THREAD_COUNTS.size();
vector<vector<double>> results(total_configs, vector<double>(SIZES.size()));
// Расчёты
for (size_t s_idx = 0; s_idx < SIZES.size(); s_idx++) { int N = SIZES[s_idx];
vector<vector<double>> A; vector<double> b; generateSystem(N, A, b);
14
results[0][s_idx] = runSequential(N, A, b);
for (size_t t_idx = 0; t_idx < THREAD_COUNTS.size(); t_idx++) { results[t_idx + 1][s_idx] = runParallel(N, A, b, THREAD_COUNTS[t_idx]);
}
vector<vector<double>>().swap(A); vector<double>().swap(b);
}
// Вывод таблицы
cout << "\n=== PERFORMANCE RESULTS (SEIDEL METHOD) ===" << endl; printDoubleLine(SIZES.size());
cout << left << setw(W_LABEL) << "Parameter" << " |"; for (int N : SIZES) {
cout << " " << left << setw(W_DATA) << N << "|";
}
cout << endl;
printSeparatorLine(SIZES.size());
cout << left << setw(W_LABEL) << "Serial (ms)" << " |"; for (size_t s_idx = 0; s_idx < SIZES.size(); s_idx++) {
cout << " " << left << setw(W_DATA) << fixed << setprecision(3) << results[0][s_idx] <<
"|";
}
cout << endl;
for (size_t t_idx = 0; t_idx < THREAD_COUNTS.size(); t_idx++) { string label = to_string(THREAD_COUNTS[t_idx]) + " threads (ms)"; cout << left << setw(W_LABEL) << label << " |";
for (size_t s_idx = 0; s_idx < SIZES.size(); s_idx++) { 15
cout << " " << left << setw(W_DATA) << fixed << setprecision(3) << results[t_idx + 1][s_idx] << "|";
}
cout << endl;
}
printDoubleLine(SIZES.size());
return 0;
}
16
ПРИЛОЖЕНИЕ Б Блок-схемы алгоритмов программы
Блок-схема последовательного алгоритма решения СЛАУ методом Зейделя
17
Блок-схема параллельного (OpenMP) алгоритма решения СЛАУ методом Зейделя
18
