DAS_2023_1/podkorytova_yulia_lab_6/README.md

100 lines
5.0 KiB
Markdown
Raw Permalink Normal View History

2024-01-10 16:37:46 +04:00
# Лабораторная работа 6. Параллельный поиск значения детерминанта матрицы
### Задание на лабораторную работу
Кратко: реализовать нахождение детерминанта квадратной матрицы.
Подробно: в лабораторной работе требуется сделать два алгоритма: обычный и параллельный. В параллельном алгоритме предусмотреть ручное задание количества потоков, каждый из которых будет выполнять нахождение отдельной группы множителей.
***
### Описание работы
Обычный алгоритм реализован в методе `findDeterminantSequential` класса `Main` (путь до файла: `/app/src/Main.java`):
```
private static int findDeterminantSequential(int[][] matrix) {
int size = matrix.length;
int determinant = 0;
if (size == 1) {
determinant = matrix[0][0];
} else if (size == 2) {
determinant = matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0];
} else {
for (int i = 0; i < size; i++) {
int[][] subMatrix = new int[size - 1][size - 1];
for (int j = 1; j < size; j++) {
for (int k = 0; k < size; k++) {
if (k < i) {
subMatrix[j - 1][k] = matrix[j][k];
} else if (k > i) {
subMatrix[j - 1][k - 1] = matrix[j][k];
}
}
}
determinant += Math.pow(-1, i) * matrix[0][i] * findDeterminantSequential(subMatrix);
}
}
return determinant;
}
```
Параллельный алгоритм реализован в методе `findDeterminantParallel` класса `Main` (путь до файла: `/app/src/Main.java`):
```
private static int findDeterminantParallel(int[][] matrix, int threadCount) throws InterruptedException {
int size = matrix.length;
int determinant = 0;
if (size == 1) {
determinant = matrix[0][0];
}
else if (size == 2) {
determinant = matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0];
}
else {
ExecutorService executor = Executors.newFixedThreadPool(threadCount);
int[] subDeterminants = new int[size];
for (int i = 0; i < size; i++) {
int[][] subMatrix = new int[size - 1][size - 1];
for (int j = 1; j < size; j++) {
for (int k = 0; k < size; k++) {
if (k < i) {
subMatrix[j - 1][k] = matrix[j][k];
} else if (k > i) {
subMatrix[j - 1][k - 1] = matrix[j][k];
}
}
}
final int row = i;
executor.submit(() -> {
subDeterminants[row] = findDeterminantSequential(subMatrix);
});
}
executor.shutdown();
try {
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
for (int i = 0; i < size; i++) {
determinant += matrix[0][i] * Math.pow(-1, i) * subDeterminants[i];
}
}
return determinant;
}
```
В методе создается пул потоков с помощью `ExecutorService` и указанным количеством потоков `threadCount`.
Класс `ExecutorService` используется для управления потоками, методы `shutdown` и `awaitTermination` используются для корректного завершения работы потоков.
Метод `findDeterminantSequential` используется для вычисления подопределителей в каждом потоке.
***
### Результаты
***Результат работы***
![](images/res.jpg)
На матрицах размером от 5x5 до 8x8 последовательный алгоритм справляется быстрее параллельного,
а на матрицах размером 9x9 и больше параллельный алгоритм справляется быстрее последовательного.
***Вывод:*** при вычислении детерминантов квадратных матриц небольших размеров использование параллельного алгоритма дает проигрыш в производительности использованию последовательного алгоритма. Параллельное умножение матриц будет эффективнее, если размер матриц больше, чем 9x9.
### Ссылка на видео:
https://drive.google.com/file/d/1cN41hHbEbeRizf0qSu1EE8LEHAL1Src1/view?usp=sharing