kurushina_ksenia_lab_6

This commit is contained in:
Kseniy 2024-12-09 20:01:43 +04:00
parent effeb9b8cd
commit e83e9844f7
3 changed files with 118 additions and 0 deletions

View File

@ -0,0 +1,53 @@
# Лабораторная работа №6: Определение детерминанта матрицы с использованием параллельных вычислений
## **Задание**
Необходимо разработать два алгоритма для вычисления детерминанта квадратной матрицы:
1. **Обычный алгоритм** — выполняется последовательно.
2. **Параллельный алгоритм**с возможностью ручного задания количества потоков. Каждый поток отвечает за вычисление определённой группы множителей.
---
## **Описание работы программы**
Программа предназначена для вычисления детерминанта квадратной матрицы двумя способами:
- **Обычным (последовательным)** методом.
- **Параллельным**, который ускоряет выполнение за счёт многопоточности.
### **Обычный алгоритм**
1. **`minor(matrix, row, col)`**
- Вспомогательная функция для формирования минора матрицы. Удаляет указанную строку и столбец, подготавливая данные для рекурсивного вычисления.
2. **`determinant(matrix)`**
- Основная функция для вычисления детерминанта. Использует метод разложения Лапласа.
- Для матриц 2x2 результат вычисляется напрямую.
- Для матриц большего размера рекурсивно вызывает себя для вычисления детерминантов подматриц.
### **Параллельный алгоритм**
1. **`parallel_determinant(matrix, num_threads=4)`**
- Основная функция, распределяющая вычисления детерминанта между потоками.
- Количество потоков задаётся вручную.
2. **`worker(start_row, end_row)`**
- Вспомогательная функция, используемая потоками. Выполняет вычисления на заданном диапазоне строк.
- Результаты отдельных потоков объединяются для получения итогового детерминанта.
---
## **Особенности реализации**
- Вычисления для небольших матриц выполняются быстрее обычным алгоритмом.
- Параллельный подход показывает значительное ускорение при обработке больших матриц (при оптимальной настройке количества потоков).
---
## **Результаты работы**
Для каждой матрицы программа выводит:
- Значение детерминанта, рассчитанное обоими алгоритмами.
- Время выполнения для каждого из методов.
Результаты тестирования представлены в виде графиков и таблиц, сохранённых в PNG-файлах проекта.
---
## **Видео**
https://cloud.mail.ru/public/L7Wf/o3nkwpAGx

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

View File

@ -0,0 +1,65 @@
import threading
#fix
import time
import random
import numpy as np
from concurrent.futures import ThreadPoolExecutor
def gaussian_determinant(matrix):
n = len(matrix)
mat = [row[:] for row in matrix]
for i in range(n):
max_row = max(range(i, n), key=lambda r: abs(mat[r][i]))
mat[i], mat[max_row] = mat[max_row], mat[i]
if mat[i][i] == 0:
return 0
for j in range(i + 1, n):
factor = mat[j][i] / mat[i][i]
for k in range(i, n):
mat[j][k] -= mat[i][k] * factor
det = 1
for i in range(n):
det *= mat[i][i]
return det
def parallel_determinant(matrix, num_threads=4):
n = len(matrix)
result = []
def worker(start_row, end_row):
partial_det = 1
for i in range(start_row, end_row):
partial_det *= matrix[i][i]
result.append(partial_det)
with ThreadPoolExecutor(max_workers=num_threads) as executor:
rows_per_thread = n // num_threads
futures = [executor.submit(worker, i * rows_per_thread, (i + 1) * rows_per_thread) for i in range(num_threads)]
for future in futures:
future.result()
return sum(result)
def generate_matrix(size):
return [[random.randint(1, 10) for _ in range(size)] for _ in range(size)]
matrix_sizes = [100, 300, 500]
num_threads = 4
for size in matrix_sizes:
print(f"\nБенчмарки для матрицы {size}x{size}:")
matrix = generate_matrix(size)
start = time.time()
det_seq = gaussian_determinant(matrix)
end = time.time()
print(f"Детерминант (последовательно, метод Гаусса): {det_seq}, время: {end - start:.5f} сек")
start = time.time()
det_par = parallel_determinant(matrix, num_threads=num_threads)
end = time.time()
print(f"Детерминант (параллельно): {det_par}, время: {end - start:.5f} сек")