rogashova_ekaterina_lab_6 #214
BIN
rogashova_ekaterina_lab_6/img.png
Normal file
BIN
rogashova_ekaterina_lab_6/img.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 45 KiB |
114
rogashova_ekaterina_lab_6/maindet.py
Normal file
114
rogashova_ekaterina_lab_6/maindet.py
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
import time
|
||||||
|
import multiprocessing
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
def determinant_sequential(matrix):
|
||||||
|
n = len(matrix)
|
||||||
|
mat = np.copy(matrix)
|
||||||
|
|
||||||
|
for i in range(n):
|
||||||
|
max_row = i
|
||||||
|
for k in range(i + 1, n):
|
||||||
|
if abs(mat[k][i]) > abs(mat[max_row][i]):
|
||||||
|
max_row = k
|
||||||
|
|
||||||
|
if abs(mat[max_row][i]) < 1e-9:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
mat[[i, max_row]] = mat[[max_row, i]]
|
||||||
|
|
||||||
|
for k in range(i + 1, n):
|
||||||
|
factor = mat[k][i] / mat[i][i]
|
||||||
|
for j in range(i, n):
|
||||||
|
mat[k][j] -= factor * mat[i][j]
|
||||||
|
|
||||||
|
det = 1
|
||||||
|
for i in range(n):
|
||||||
|
det *= mat[i][i]
|
||||||
|
return det
|
||||||
|
|
||||||
|
def determinant_parallel_worker(matrix_part, row_indices):
|
||||||
|
n_part = len(matrix_part)
|
||||||
|
local_matrix = np.copy(matrix_part)
|
||||||
|
local_row_indices = np.copy(row_indices)
|
||||||
|
|
||||||
|
for i in range(n_part):
|
||||||
|
max_row = i
|
||||||
|
for k in range(i + 1, n_part):
|
||||||
|
if abs(local_matrix[k][i]) > abs(local_matrix[max_row][i]):
|
||||||
|
max_row = k
|
||||||
|
|
||||||
|
if abs(local_matrix[max_row][i]) < 1e-9:
|
||||||
|
return 0, local_row_indices
|
||||||
|
|
||||||
|
local_matrix[[i, max_row]] = local_matrix[[max_row, i]]
|
||||||
|
local_row_indices[[i, max_row]] = local_row_indices[[max_row, i]]
|
||||||
|
|
||||||
|
for k in range(i + 1, n_part):
|
||||||
|
factor = local_matrix[k][i] / local_matrix[i][i]
|
||||||
|
for j in range(i, n_part):
|
||||||
|
local_matrix[k][j] -= factor * local_matrix[i][j]
|
||||||
|
|
||||||
|
det_part = 1
|
||||||
|
for i in range(n_part):
|
||||||
|
det_part *= local_matrix[i][i]
|
||||||
|
return det_part, local_row_indices
|
||||||
|
|
||||||
|
|
||||||
|
def determinant_parallel(matrix, num_threads):
|
||||||
|
n = len(matrix)
|
||||||
|
if n == 1:
|
||||||
|
return matrix[0][0]
|
||||||
|
|
||||||
|
if num_threads > n:
|
||||||
|
num_threads = n
|
||||||
|
|
||||||
|
chunk_size = n // num_threads
|
||||||
|
|
||||||
|
with multiprocessing.Pool(processes=num_threads) as pool:
|
||||||
|
results = []
|
||||||
|
row_indices = np.arange(n)
|
||||||
|
for i in range(num_threads):
|
||||||
|
start_row = i * chunk_size
|
||||||
|
end_row = (i + 1) * chunk_size if i < num_threads - 1 else n
|
||||||
|
res = pool.apply_async(determinant_parallel_worker,
|
||||||
|
(matrix[start_row:end_row, :], row_indices[start_row:end_row]))
|
||||||
|
results.append(res)
|
||||||
|
|
||||||
|
partial_dets = []
|
||||||
|
for res in results:
|
||||||
|
det_part, row_indices_part = res.get()
|
||||||
|
partial_dets.append(det_part)
|
||||||
|
|
||||||
|
|
||||||
|
final_det = 1
|
||||||
|
for det_part in partial_dets:
|
||||||
|
final_det *= det_part
|
||||||
|
|
||||||
|
return final_det
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def calculate_determinant(matrix, num_threads):
|
||||||
|
if num_threads == 1:
|
||||||
|
return determinant_sequential(matrix)
|
||||||
|
else:
|
||||||
|
return determinant_parallel(matrix, num_threads)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sizes = [100, 300, 500]
|
||||||
|
num_threads_list = [1, 2, 4]
|
||||||
|
|
||||||
|
for size in sizes:
|
||||||
|
matrix = np.random.rand(size, size)
|
||||||
|
for num_threads in num_threads_list:
|
||||||
|
start_time = time.time()
|
||||||
|
if num_threads == 1:
|
||||||
|
calculation_method = "Последовательный"
|
||||||
|
else:
|
||||||
|
calculation_method = f"Параллельный ({num_threads} потоков)"
|
||||||
|
det = calculate_determinant(matrix, num_threads)
|
||||||
|
end_time = time.time()
|
||||||
|
print(
|
||||||
|
f"Размер матрицы: {size}x{size}, Метод вычисления: {calculation_method}, Время: {end_time - start_time:.4f} сек.")
|
17
rogashova_ekaterina_lab_6/readme.md
Normal file
17
rogashova_ekaterina_lab_6/readme.md
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
# Лабораторная работа №6
|
||||||
|
|
||||||
|
## Описание
|
||||||
|
Написана программа, которая вычисляет определитель квадратной матрицы двумя способами:
|
||||||
|
последовательно и параллельно, и сравнивает время их выполнения.
|
||||||
|
|
||||||
|
Для каждой матрицы вычисляется детерминант с использованием различных количеств потоков (1, 2 и 4) и выводится время работы.
|
||||||
|
|
||||||
|
## Вывод работы
|
||||||
|
Для матрицы 300x300 и 500x500 результаты показывают значительное преимущество параллельных вычислений.
|
||||||
|
Параллельные вычисления с 4 потоками значительно более эффективны, чем с 2 потоками для больших матриц (300x300 и 500x500). Это может указывать на то, что алгоритм выгодно распараллеливается, и использование большего числа потоков помогает снизить время исполнения.
|
||||||
|
Однако на малых матрицах (100x100) из-за высокой нагрузки на управление потоками производительность уменьшается (или не значительная).
|
||||||
|
|
||||||
|
![img.png](img.png)
|
||||||
|
|
||||||
|
## Видео
|
||||||
|
Работоспособность представлена на [видео](https://vk.com/video204968285_456240930).
|
Loading…
Reference in New Issue
Block a user