DAS_2024_1/kosheev_maksim_lab_6/main.py

86 lines
3.9 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
import time
from multiprocessing import Pool
# Функция для вычисления детерминанта с использованием метода Гаусса
def determinant_gauss(matrix):
n = matrix.shape[0]
A = matrix.astype(float) # Создаём копию матрицы, чтобы не изменять исходную
det = 1 # Начальная величина детерминанта
for i in range(n):
# Ищем максимальный элемент в текущем столбце для уменьшения ошибок округления
max_row = np.argmax(np.abs(A[i:n, i])) + i
if A[max_row, i] == 0:
return 0 # Если на диагонали ноль, то детерминант равен нулю
# Переставляем строки
if max_row != i:
A[[i, max_row]] = A[[max_row, i]]
det *= -1 # Каждая перестановка меняет знак детерминанта
# Обнуляем элементы ниже диагонали
for j in range(i + 1, n):
factor = A[j, i] / A[i, i]
A[j, i:] -= factor * A[i, i:]
# Произведение элементов на диагонали
for i in range(n):
det *= A[i, i]
return det
# Функция для вычисления детерминанта с многопроцессностью
def parallel_determinant_worker(index_range, matrix):
n = matrix.shape[0]
A = matrix.astype(float)
det = 1
for i in range(index_range[0], index_range[1]):
# Ищем максимальный элемент в текущем столбце
max_row = np.argmax(np.abs(A[i:n, i])) + i
if A[max_row, i] == 0:
return 0
if max_row != i:
A[[i, max_row]] = A[[max_row, i]]
det *= -1
for j in range(i + 1, n):
factor = A[j, i] / A[i, i]
A[j, i:] -= factor * A[i, i:]
return det
# Функция для параллельного вычисления детерминанта
def determinant_parallel(matrix, num_processes):
n = matrix.shape[0]
# Делим работу на блоки
block_size = n // num_processes
blocks = [(i * block_size, (i + 1) * block_size) for i in range(num_processes)]
with Pool(processes=num_processes) as pool:
results = pool.starmap(parallel_determinant_worker, [(block, matrix) for block in blocks])
# Объединяем результаты
det = sum(results)
return det
# Функция для запуска бенчмарков
def run_benchmarks():
matrix_sizes = [100, 300, 500,1000,1200] # Размеры матриц
for size in matrix_sizes:
matrix = np.random.rand(size, size) # Генерация случайной матрицы
print(f"--- Benchmark для матрицы {size}x{size} ---")
# Бенчмарк для последовательного вычисления детерминанта
start_time = time.time()
seq_det = determinant_gauss(matrix)
seq_time = time.time() - start_time
print(f"Последовательное время для {size}x{size}: {seq_time:.4f} секунд")
# Бенчмарк для параллельного вычисления с разным числом потоков
for num_processes in [1, 2, 4, 6, 8, 12, 16]:
start_time = time.time()
par_det = determinant_parallel(matrix, num_processes)
par_time = time.time() - start_time
speedup = seq_time / par_time if par_time > 0 else 0
print(f"Параллельное время с {num_processes} потоками: {par_time:.4f} секунд, Ускорение: {speedup:.2f}")
# Запуск бенчмарков
if __name__ == '__main__':
run_benchmarks()