DAS_2024_1/pupkov_alexey_lab_6/main.py

85 lines
3.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import numpy as np
from concurrent.futures import ThreadPoolExecutor
import time
import argparse
# Вычисляет детерминант матрицы с использованием метода Гаусса
def determinant_sequential(matrix):
n = matrix.shape[0]
mat = matrix.copy().astype(float)
for i in range(n):
if mat[i, i] == 0:
for j in range(i + 1, n):
if mat[j, i] != 0:
mat[[i, j]] = mat[[j, i]] # Меняем строки
break
for j in range(i + 1, n):
factor = mat[j, i] / mat[i, i]
mat[j] -= factor * mat[i]
det = np.prod(np.diag(mat))
return det
# Функция для вычисления минора
def calculate_minor(matrix, i, j):
minor = np.delete(matrix, i, axis=0)
minor = np.delete(minor, j, axis=1)
return np.linalg.det(minor)
# Параллельное вычисление
def determinant_parallel(matrix, num_threads):
if num_threads == 1:
return determinant_sequential(matrix)
n = len(matrix)
results = []
with ThreadPoolExecutor(max_workers=num_threads) as executor:
futures = [
executor.submit(lambda x: ((-1) ** x) * matrix[0, x] * calculate_minor(matrix, 0, x), i)
for i in range(n)
]
for future in futures:
results.append(future.result())
return sum(results)
def benchmark(matrix_sizes, num_threads_list):
for size in matrix_sizes:
matrix = np.random.rand(size, size)
print(f"\nРазмер матрицы: {size}x{size}")
# Бенчмарк для последовательного алгоритма
start_time = time.time()
det_seq = determinant_sequential(matrix)
sequential_time = time.time() - start_time
print(f"Последовательный алгоритм занял: {sequential_time:.4f} секунд")
# Бенчмарк для параллельного алгоритма
for num_threads in num_threads_list:
start_time = time.time()
det_par = determinant_parallel(matrix, num_threads)
parallel_time = time.time() - start_time
print(f"Параллельный алгоритм с {num_threads} потоками занял: {parallel_time:.4f} секунд")
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Запуск бенчмарков для последовательного и параллельного вычисления детерминанта.")
parser.add_argument(
"--threads",
type=int,
nargs="+",
required=True,
help="Список количества потоков для параллельного алгоритма (например, --threads 1 2 4 8)"
)
args = parser.parse_args()
# Задание размеров матриц для тестов
matrix_sizes = [100, 300, 500]
num_threads_list = args.threads # Получаем список потоков из аргументов командной строки
# Запуск бенчмарка
benchmark(matrix_sizes, num_threads_list)