Скачиваний:
0
Добавлен:
27.12.2025
Размер:
644.11 Кб
Скачать

int 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