85 lines
3.2 KiB
Python
85 lines
3.2 KiB
Python
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)
|