# Лабораторная работа 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