Merge pull request 'tukaeva_alfiya_lab_6' (#114) from tukaeva_alfiya_lab_6 into main
Reviewed-on: #114
This commit is contained in:
commit
e1da6f26ab
29
tukaeva_alfiya_lab_6/README.md
Normal file
29
tukaeva_alfiya_lab_6/README.md
Normal file
@ -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
|
117
tukaeva_alfiya_lab_6/project/main.py
Normal file
117
tukaeva_alfiya_lab_6/project/main.py
Normal file
@ -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()
|
BIN
tukaeva_alfiya_lab_6/result.png
Normal file
BIN
tukaeva_alfiya_lab_6/result.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 47 KiB |
Loading…
Reference in New Issue
Block a user