import numpy as np import time from multiprocessing import Pool np.seterr(over='ignore') # Функция для вычисления детерминанта методом Гаусса def compute_determinant_gauss(mat): size = mat.shape[0] matrix_copy = mat.astype(float) # Копируем матрицу, чтобы не изменять исходную determinant = 1.0 # Начальное значение детерминанта for k in range(size): # Находим максимальный элемент в текущем столбце для уменьшения ошибок округления max_index = np.argmax(np.abs(matrix_copy[k:size, k])) + k if matrix_copy[max_index, k] == 0: return 0 # Если на главной диагонали ноль, детерминант равен нулю # Меняем местами строки if max_index != k: matrix_copy[[k, max_index]] = matrix_copy[[max_index, k]] determinant *= -1 # Каждая перестановка меняет знак детерминанта # Обнуляем элементы ниже главной диагонали for m in range(k + 1, size): multiplier = matrix_copy[m, k] / matrix_copy[k, k] matrix_copy[m, k:] -= multiplier * matrix_copy[k, k:] # Произведение элементов на главной диагонали for j in range(size): determinant *= matrix_copy[j, j] return determinant # Функция для параллельного вычисления детерминанта def parallel_worker(index_range, mat): size = mat.shape[0] matrix_copy = mat.astype(float) det = 1.0 for k in range(index_range[0], index_range[1]): max_index = np.argmax(np.abs(matrix_copy[k:size, k])) + k if matrix_copy[max_index, k] == 0: return 0 if max_index != k: matrix_copy[[k, max_index]] = matrix_copy[[max_index, k]] det *= -1 for m in range(k + 1, size): multiplier = matrix_copy[m, k] / matrix_copy[k, k] matrix_copy[m, k:] -= multiplier * matrix_copy[k, k:] return det # Функция для параллельного вычисления детерминанта def compute_parallel_determinant(mat, num_workers): size = mat.shape[0] block_size = size // num_workers ranges = [(i * block_size, (i + 1) * block_size) for i in range(num_workers)] with Pool(processes=num_workers) as pool: results = pool.starmap(parallel_worker, [(block, mat) for block in ranges]) # Объединяем результаты total_determinant = sum(results) return total_determinant # Функция для запуска тестов производительности def execute_benchmarks(): sizes = [100, 300, 500] # Размеры матриц for size in sizes: random_matrix = np.random.rand(size, size) # Генерация случайной матрицы print(f"--- Тест производительности для матрицы {size}x{size} ---") # Последовательное вычисление детерминанта start_time = time.time() sequential_det = compute_determinant_gauss(random_matrix) seq_duration = time.time() - start_time print(f"Время последовательного вычисления для {size}x{size}: {seq_duration:.4f} секунд") # Параллельное вычисление с различным количеством процессов for workers in [1, 2, 4, 6, 8, 12, 16]: start_time = time.time() parallel_det = compute_parallel_determinant(random_matrix, workers) par_duration = time.time() - start_time speedup_ratio = seq_duration / par_duration if par_duration > 0 else 0 print(f"Параллельное время с {workers} процессами: {par_duration:.4f} секунд, Ускорение: {speedup_ratio:.2f}") # Запуск тестов производительности if __name__ == '__main__': execute_benchmarks()