diff --git a/lazarev_andrey_lab_6/README.md b/lazarev_andrey_lab_6/README.md new file mode 100644 index 0000000..1c9c861 --- /dev/null +++ b/lazarev_andrey_lab_6/README.md @@ -0,0 +1,32 @@ +# Лабораторная работа №6 + +## Задание + +Реализовать последователный и параллельный алгоритм поиска детерминанта матрицы размером 100x100, 300x300, 500x500 элементов, сравнить результаты. + +## Описание алгоритмов + +### Последовательное поиск детерминанта + +- Использует метод Гаусса для приведения матрицы к верхней треугольной форме. Детерминант равен произведению элементов на диагонали. Время работы — O(n³). + +### Параллельное поиск детерминанта + +- Разделяет матрицу на блоки, каждый из которых обрабатывается отдельным потоком. + +### Поиск с использованием библиотеки Numpy + +- Использует оптимизированную функцию np.linalg.det, которая применяет методы, такие как LU-разложение, для быстрого вычисления детерминанта. + +## Результаты + +![](report.png "") + +### Вывод +- Параллельное умножение матриц эффективно при работе с большими матрицами при увеличении потоков. +- Последовательное умножение матриц эффективно использовать при меньших размерах матриц, где выйгрыш от управления потоками минимален. +- Numpy показал блестящий результат. + +## Видеодемонстрация работоспособности + +[Демонстрация работы](https://files.ulstu.ru/s/nWF9CGBGA6Kxw5T) \ No newline at end of file diff --git a/lazarev_andrey_lab_6/main.py b/lazarev_andrey_lab_6/main.py new file mode 100644 index 0000000..ed76ae0 --- /dev/null +++ b/lazarev_andrey_lab_6/main.py @@ -0,0 +1,77 @@ +import numpy as np +from concurrent.futures import ProcessPoolExecutor +import time + +# Функция последовательного поиска детерминанта +def det_sequential(matrix): + n = len(matrix) + det = 1 + + for i in range(n): + if matrix[i][i] == 0: + for j in range(i + 1, n): + if matrix[j][i] != 0: + matrix[i], matrix[j] = matrix[j], matrix[i] + det *= -1 + break + else: + return 0 + + for j in range(i + 1, n): + factor = matrix[j][i] / matrix[i][i] + for k in range(i, n): + matrix[j][k] -= factor * matrix[i][k] + + det *= matrix[i][i] + + return det + +# Функция поиска детерминанта с numpy +def det_numpy(A): + return np.linalg.det(A) + +# Функция параллельного поиска детерминанта +def det_parallel(A, num_threads): + n = len(A) + C = [] + step = n // num_threads + + with ProcessPoolExecutor(max_workers=num_threads) as executor: + futures = [] + for i in range(num_threads): + start_row = i * step + end_row = (i + 1) * step if i != num_threads - 1 else n + a_slice = A[start_row:end_row, start_row:end_row] + + futures.append(executor.submit(det_sequential, a_slice)) + for future in futures: + C.append(future.result()) + + return np.prod(C) + +# Пример использования +if __name__ == "__main__": + matrix_sizes = [100, 300, 500] + num_threads = [2, 4, 5, 10] + for n in matrix_sizes: + A = np.random.rand(n, n) + + # Поиск с numpy + start_np = time.time() + nump = det_numpy(A) + end_np = time.time() + print(f'Детерминант матрицы {n}x{n} с numpy: {(end_np - start_np):.3f} с.') + + # Последовательное умножение + start_seq = time.time() + sequential = det_sequential(A) + end_seq = time.time() + print(f'Детерминант матрицы {n}x{n} последовательно: {(end_seq - start_seq):.3f} с.') + + # Параллельное умножение + for thread in num_threads: + start_par = time.time() + parallel = det_parallel(A, thread) + end_par = time.time() + print(f'Детерминант матрицы {n}x{n} параллельно для {thread} потоков: {(end_par - start_par):.3f} с.') + print('') \ No newline at end of file diff --git a/lazarev_andrey_lab_6/report.png b/lazarev_andrey_lab_6/report.png new file mode 100644 index 0000000..ff7b075 Binary files /dev/null and b/lazarev_andrey_lab_6/report.png differ