diff --git a/kalyshev_yan_lab_6/Dockerfile b/kalyshev_yan_lab_6/Dockerfile new file mode 100644 index 0000000..4c27c68 --- /dev/null +++ b/kalyshev_yan_lab_6/Dockerfile @@ -0,0 +1,10 @@ +FROM python:3 + +WORKDIR /usr/src/app + +COPY requirements.txt ./ +RUN pip install --no-cache-dir -r requirements.txt + +COPY . . + +CMD [ "python", "./main.py" ] diff --git a/kalyshev_yan_lab_6/README.md b/kalyshev_yan_lab_6/README.md new file mode 100644 index 0000000..d1291ec --- /dev/null +++ b/kalyshev_yan_lab_6/README.md @@ -0,0 +1,20 @@ +# Отчет. Лабораторная работа 6 + +## Описание + +В ходе лабораторной работы были реализованы алгоритмы нахождение детерминанта квадратной матрицы на python: обычный и параллельный. + +![result](./images/result.png) +Из результатов видно, что на маленьких матрицах параллелизм не имеет смысла, но с увеличением размера матриц, время обработки значительно падает по сравнению с обычным алгоритмом. + +## Как запустить + +Для того, чтобы запустить сервисы, необходимо выполнить следующие действия: + +1. Установить и запустить Docker Engine или Docker Desktop +2. Через консоль перейти в папку, в которой расположен файл docker-compose.yml +3. Выполнить команду для запуска: + +``` +docker compose up -d +``` diff --git a/kalyshev_yan_lab_6/docker-compose.yml b/kalyshev_yan_lab_6/docker-compose.yml new file mode 100644 index 0000000..4f445ae --- /dev/null +++ b/kalyshev_yan_lab_6/docker-compose.yml @@ -0,0 +1,3 @@ +services: + main: + build: . diff --git a/kalyshev_yan_lab_6/images/result.png b/kalyshev_yan_lab_6/images/result.png new file mode 100644 index 0000000..c692309 Binary files /dev/null and b/kalyshev_yan_lab_6/images/result.png differ diff --git a/kalyshev_yan_lab_6/main.py b/kalyshev_yan_lab_6/main.py new file mode 100644 index 0000000..23df401 --- /dev/null +++ b/kalyshev_yan_lab_6/main.py @@ -0,0 +1,91 @@ +from multiprocessing import Pool, cpu_count +import time +import numpy as np + + +def determinant(matrix): + matrix = np.array(matrix, dtype=float) + n = matrix.shape[0] + + for i in range(n): + if matrix[i, i] == 0: + for j in range(i + 1, n): + if matrix[j, i] != 0: + matrix[[i, j]] = matrix[[j, i]] + break + if matrix[i, i] == 0: + return 0 + + for j in range(i + 1, n): + factor = matrix[j, i] / matrix[i, i] + matrix[j] -= factor * matrix[i] + + det = 1.0 + for i in range(n): + det *= matrix[i, i] + return det + + +# Пример использования +A = np.random.rand(100, 100) +print(determinant(A)) + + +def _determinant_parallel_chunk(args): + matrix, start_row, end_row = args + n = matrix.shape[0] + for i in range(start_row, end_row): + for j in range(i + 1, n): + factor = matrix[j, i] / matrix[i, i] + matrix[j] -= factor * matrix[i] + return matrix + + +def determinant_parallel(matrix, num_processes=None): + if num_processes is None: + num_processes = cpu_count() + + matrix = np.array(matrix, dtype=float) + n = matrix.shape[0] + + chunk_size = n // num_processes + tasks = [ + ( + matrix.copy(), + i * chunk_size, + (i + 1) * chunk_size if i != num_processes - 1 else n, + ) + for i in range(num_processes) + ] + + with Pool(processes=num_processes) as pool: + results = pool.map(_determinant_parallel_chunk, tasks) + + # В каждой части делаем лишь частичное вычитание + # Теперь выполняем окончательное вычисление детерминанта + det = 1.0 + for i in range(n): + det *= results[0][i, i] + return det + + +# Пример использования +A = np.random.rand(100, 100) +print(determinant_parallel(A, num_processes=4)) + +sizes = [100, 300, 500] +num_processes = 12 + +for size in sizes: + A = np.random.rand(size, size) + start_time = time.time() + det_seq = determinant(A) + seq_time = time.time() - start_time + + start_time = time.time() + det_par = determinant_parallel(A, num_processes=num_processes) + par_time = time.time() - start_time + + print( + f"Size {size}x{size}: Sequential Time = {seq_time:.4f} s, Parallel Time = {par_time:.4f} s" + ) diff --git a/kalyshev_yan_lab_6/requirements.txt b/kalyshev_yan_lab_6/requirements.txt new file mode 100644 index 0000000..24ce15a --- /dev/null +++ b/kalyshev_yan_lab_6/requirements.txt @@ -0,0 +1 @@ +numpy