kalyshev_yan_lab_6 #235

Merged
Alexey merged 2 commits from kalyshev_yan_lab_6 into main 2024-12-15 13:35:48 +04:00
6 changed files with 125 additions and 0 deletions
Showing only changes of commit 4390166883 - Show all commits

View File

@ -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" ]

View File

@ -0,0 +1,20 @@
# Отчет. Лабораторная работа 6
## Описание
В ходе лабораторной работы были реализованы алгоритмы нахождение детерминанта квадратной матрицы на python: обычный и параллельный.
![result](./images/result.png)
Из результатов видно, что на маленьких матрицах параллелизм не имеет смысла, но с увеличением размера матриц, время обработки значительно падает по сравнению с обычным алгоритмом.
## Как запустить
Для того, чтобы запустить сервисы, необходимо выполнить следующие действия:
1. Установить и запустить Docker Engine или Docker Desktop
2. Через консоль перейти в папку, в которой расположен файл docker-compose.yml
3. Выполнить команду для запуска:
```
docker compose up -d
```

View File

@ -0,0 +1,3 @@
services:
main:
build: .

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

View File

@ -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"
)

View File

@ -0,0 +1 @@
numpy