diff --git a/martysheva_tamara_lab_6/README.md b/martysheva_tamara_lab_6/README.md new file mode 100644 index 0000000..35bdaba --- /dev/null +++ b/martysheva_tamara_lab_6/README.md @@ -0,0 +1,98 @@ +# Лабораторная работа №6 - Параллельный поиск значения детерминанта матрицы +**Кратко**: реализовать нахождение детерминанта квадратной матрицы. + +**Подробно**: в лабораторной работе требуется сделать два алгоритма: обычный и параллельный. В параллельном алгоритме предусмотреть ручное задание количества потоков, каждый из которых будет выполнять нахождение отдельной группы множителей. +*** +## *Ход работы:* +### Обычный алгоритм SequentialDeterminant: +``` + public static int SequentialDeterminant(int[][] matrix, int size) { + if (size == 1) { + return matrix[0][0]; + } + else if (size == 2) { + return matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0]; + } + else { + int det = 0; + for (int i = 0; i < size; i++) { + var submatrix = Submatrix(matrix, i); + det += Math.pow(-1, i) * matrix[0][i] * SequentialDeterminant(submatrix, submatrix.length); + } + return det; + } + } +``` +Если матрица имеет размер более 2х2, то вычисление определителя происходит с рекурсивным вызовом с использованием миноров: +``` + private static int[][] Submatrix(int[][] matrix, int excludeCol) { + int size = matrix.length - 1; + int[][] submatrix = new int[size][size]; + + int rowIndex = 0; + for (int i = 0; i < matrix.length; i++) { + if (i == 0) { + continue; + } + int colIndex = 0; + for (int j = 0; j < matrix[i].length; j++) { + if (j == excludeCol) { + continue; + } + submatrix[rowIndex][colIndex] = matrix[i][j]; + colIndex++; + } + rowIndex++; + } + return submatrix; + } +``` +Метод создает подматрицу матрицы, исключая указанный столбец. +### Параллельный алгоритм ParallelDeterminant: +``` + public static int ParallelDeterminant(int[][] matrix, int size, int threads) { + if (size == 1) { + return matrix[0][0]; + } + else if (size == 2) { + return matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0]; + } + else { + int det = 0; + ExecutorService executor = Executors.newFixedThreadPool(threads); + List> tasks = new ArrayList<>(); + + for (int i = 0; i < size; i++) { + var submatrix = Submatrix(matrix, i); + int finalI = i; + tasks.add(() -> (int) Math.pow(-1, finalI) * matrix[0][finalI] * SequentialDeterminant(submatrix, submatrix.length)); + } + + try { + List> futures = executor.invokeAll(tasks); + for (Future future : futures) { + det += future.get(); + } + } catch (InterruptedException | ExecutionException e) { + e.printStackTrace(); + return -1; + } finally { + executor.shutdown(); + } + + return det; + } + } +``` + +Создается исполнительский сервис (ExecutorService) с фиксированным числом потоков. Создается список задач (tasks), где каждая задача представляет собой вычисление минора для соответствующего столбца. +После запуска задач в пуле потоков, ожидаем завершения выполнения. Далее формируется конечный результат. +### Результат +_На больших матрицах алгоритм работает очень долго_* + +![](images/result.jpg "") + +* На матрице 6x6 последовательный алгоритм справился намного быстрее параллельного. +* На матрице 9x9 уже параллельный алгоритм справляется быстрее. +* На матрице 12x12 параллельный алгоритм тоже лидирует. + diff --git a/martysheva_tamara_lab_6/images/result.jpg b/martysheva_tamara_lab_6/images/result.jpg new file mode 100644 index 0000000..0c0a4d1 Binary files /dev/null and b/martysheva_tamara_lab_6/images/result.jpg differ diff --git a/martysheva_tamara_lab_6/myapp/Main.java b/martysheva_tamara_lab_6/myapp/Main.java new file mode 100644 index 0000000..2d26071 Binary files /dev/null and b/martysheva_tamara_lab_6/myapp/Main.java differ diff --git a/martysheva_tamara_lab_6/video.mkv b/martysheva_tamara_lab_6/video.mkv new file mode 100644 index 0000000..eaad0d2 Binary files /dev/null and b/martysheva_tamara_lab_6/video.mkv differ