diff --git a/putilin_pavel_lab_6/README.md b/putilin_pavel_lab_6/README.md new file mode 100644 index 0000000..693c1d3 --- /dev/null +++ b/putilin_pavel_lab_6/README.md @@ -0,0 +1,31 @@ +# Лабораторная работа №6: Нахождение детерминанта квадратной матрицы + +## Задание + +Необходимо реализовать два алгоритма нахождения детерминанта квадратной матрицы: +1. Обычное вычисление. +2. Параллельное вычисление с использованием многозадачности, где каждый поток будет вычислять часть матрицы. + +### Требования: +1. Обычный алгоритм нахождения детерминанта (например, через рекурсию или разложение по строкам/столбцам). +2. Параллельный алгоритм с возможностью задания количества потоков. +3. Бенчмаркинг для матриц размером 100x100, 300x300 и 500x500. + +## Структура проекта + +Проект реализован в одном файле `main.py`, который включает в себя: +- Обычное вычисление детерминанта. +- Параллельное вычисление с использованием многозадачности. +- Генерацию случайных матриц для тестирования. +- Бенчмаркинг для измерения времени выполнения обоих алгоритмов. +- Тесты для проверки корректности вычисления детерминанта. + +## Видео + +https://cloud.mail.ru/public/31aJ/RrdgK3Rik + +## Заключение + +В ходе лабораторной работы были реализованы два алгоритма вычисления детерминанта матрицы: обычный и параллельный. +Параллельное вычисление показало значительное ускорение на больших матрицах, +что подчеркивает эффективность многозадачности в вычислительных задачах. diff --git a/putilin_pavel_lab_6/main.py b/putilin_pavel_lab_6/main.py new file mode 100644 index 0000000..600a255 --- /dev/null +++ b/putilin_pavel_lab_6/main.py @@ -0,0 +1,75 @@ +import numpy as np +import threading +import time + + +def determinant_gauss(matrix): + """Вычисление детерминанта методом Гаусса""" + matrix_copy = matrix.astype(np.float64) + n = matrix_copy.shape[0] + det = 1.0 + + for i in range(n): + if matrix_copy[i, i] == 0: + for j in range(i + 1, n): + if matrix_copy[j, i] != 0: + matrix_copy[[i, j]] = matrix_copy[[j, i]] + det *= -1 + break + det *= matrix_copy[i, i] + matrix_copy[i, i:] /= matrix_copy[i, i] + + for j in range(i + 1, n): + factor = matrix_copy[j, i] + matrix_copy[j, i:] -= factor * matrix_copy[i, i:] + + return det + + +def determinant_parallel(matrix, num_threads=2): + """Параллельное вычисление детерминанта с использованием потоков""" + + def compute_row(row, matrix_copy): + n = matrix_copy.shape[0] + for i in range(row, n, num_threads): + for j in range(i + 1, n): + if matrix_copy[i, i] == 0: + continue + factor = matrix_copy[j, i] / matrix_copy[i, i] + matrix_copy[j, i:] -= factor * matrix_copy[i, i:] + + matrix_copy = matrix.astype(np.float64) + + threads = [] + for i in range(num_threads): + t = threading.Thread(target=compute_row, args=(i, matrix_copy)) + threads.append(t) + t.start() + + for t in threads: + t.join() + + return matrix_copy[-1, -1] + + +def benchmark(sizes): + for size in sizes: + matrix = np.random.randint(1, 11, (size, size)) + + start_time = time.time() + det_regular = determinant_gauss(matrix) + end_time = time.time() + regular_time = end_time - start_time + + start_time = time.time() + det_parallel = determinant_parallel(matrix, num_threads=4) + end_time = time.time() + parallel_time = end_time - start_time + + print(f"Размер матрицы: {size}x{size}") + print(f"Детерминант (последовательно): {det_regular} | Время: {regular_time} секунд") + print(f"Детерминант (параллельно): {det_parallel} | Время: {parallel_time} секунд") + print("-" * 50) + + +benchmark([100, 300, 500])