diff --git a/tukaeva_alfiya_lab_6/README.md b/tukaeva_alfiya_lab_6/README.md new file mode 100644 index 0000000..4e3d5a5 --- /dev/null +++ b/tukaeva_alfiya_lab_6/README.md @@ -0,0 +1,29 @@ +# Лабораторная работа №6 - Определение детерминанта матрицы с помощью параллельных вычислений + +## Задание + +* Кратко: реализовать нахождение детерминанта квадратной матрицы. Что такое детерминант матрицы (или определитель) можно посмотреть по ссылке. + +* Подробно: в лабораторной работе требуется сделать два алгоритма: обычный и параллельный (задание со * - реализовать это в рамках одного алгоритма). В параллельном алгоритме предусмотреть ручное задание количества потоков (число потоков = 1 как раз и реализует задание со *), каждый из которых будет выполнять нахождение отдельной группы множителей. + + +## Работа программы: + + 1. Инициализирует три матрицы размером 100x100, 300x300 и 500x500 со случайными значениями. + + 2. det(matrix) реализует алгоритм Гаусса для нахождения детерминанта квадратной матрицы. + + 3. parallel_det(matrix, num_threads=1) использует пул потоков для ускорения вычислений. Для каждой строки матрицы создается поток, который обрабатывает все строки под ней, применяя необходимые преобразования. + + +### Результат: + +![](result.png "") + +### Вывод: + +Параллельные вычисления могут значительно ускорить процесс нахождения детерминанта, особенно когда речь идет о больших матрицах. Тем не менее, иногда результаты вычисленного детерминанта могут различаться между последовательным и параллельным подходами. + + +# Видео +https://vk.com/video230744264_456239110?list=ln-LZEUeze0D4JCSQZ4LK diff --git a/tukaeva_alfiya_lab_6/project/main.py b/tukaeva_alfiya_lab_6/project/main.py new file mode 100644 index 0000000..adacac0 --- /dev/null +++ b/tukaeva_alfiya_lab_6/project/main.py @@ -0,0 +1,117 @@ +import random +import time +import copy +from multiprocessing import Pool +import concurrent.futures +from copy import deepcopy + + +class Matrix: + def __init__(self) -> None: + self.matrix_100 = [[0] * 100 for _ in range(100)] + self.matrix_300 = [[0] * 300 for _ in range(300)] + self.matrix_500 = [[0] * 500 for _ in range(500)] + + def str_matrix(self, type_list: str): + _str = "" + + current_matrix = getattr(self, type_list) + + for i in range(len(current_matrix)): + _str += "[ " + + for j in range(len(current_matrix[0])): + _str += str(current_matrix[i][j]) + " " + + _str += " ]\n" + + return _str + + +def init_matrix(matrix: Matrix, size: int): + for i in range(size): + for j in range(size): + matrix.__dict__[f"matrix_{size}"][i][j] = random.randint(0, 5) + + +def parallel_det(matrix, num_threads=1): + n = len(matrix) + m = deepcopy(matrix) + det_value = 1 + + for i in range(n): + if m[i][i] == 0: + for j in range(i + 1, n): + if m[j][i] != 0: + m[i], m[j] = m[j], m[i] + det_value *= -1 + break + else: + return 0 + + with concurrent.futures.ThreadPoolExecutor(max_workers=num_threads) as executor: + futures = [executor.submit(process_row, i, j, m, n) for j in range(i + 1, n)] + concurrent.futures.wait(futures) + + det_value *= m[i][i] + m = [list(row) for row in m] # Обновляем строки матрицы + + return det_value + + +def process_row(i, j, m, n): + factor = m[j][i] / m[i][i] + for k in range(i, n): + m[j][k] -= factor * m[i][k] + return m[j] + + +def det(matrix): + n = len(matrix) + m = [row[:] for row in matrix] + det_value = 1 + + for i in range(n): + if m[i][i] == 0: + for j in range(i + 1, n): + if m[j][i] != 0: + m[i], m[j] = m[j], m[i] + det_value *= -1 + break + else: + return 0 + + for j in range(i + 1, n): + factor = m[j][i] / m[i][i] + for k in range(i, n): + m[j][k] -= factor * m[i][k] + + det_value *= m[i][i] + + return det_value + + +def benchmark(): + matrix = Matrix() + init_matrix(matrix, 100) + init_matrix(matrix, 300) + init_matrix(matrix, 500) + + sizes = [100, 300, 500] + for size in sizes: + current_matrix = getattr(matrix, f'matrix_{size}') + + start_time = time.time() + seq_result = det(current_matrix) + seq_time = time.time() - start_time + print(f"Последовательный детерминант {size}x{size}: {seq_result}, Время: {seq_time:.6f}с") + + + start_time = time.time() + par_result = parallel_det(current_matrix, num_threads=4) # Измените число потоков по необходимости + par_time = time.time() - start_time + print(f"Параллельный детерминант {size}x{size}: {par_result}, Время: {par_time:.6f}с") + + +if __name__ == "__main__": + benchmark() diff --git a/tukaeva_alfiya_lab_6/result.png b/tukaeva_alfiya_lab_6/result.png new file mode 100644 index 0000000..c5c61fc Binary files /dev/null and b/tukaeva_alfiya_lab_6/result.png differ