diff --git a/podkorytova_yulia_lab_6/README.md b/podkorytova_yulia_lab_6/README.md new file mode 100644 index 0000000..7780602 --- /dev/null +++ b/podkorytova_yulia_lab_6/README.md @@ -0,0 +1,100 @@ +# Лабораторная работа 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 \ No newline at end of file diff --git a/podkorytova_yulia_lab_6/app/src/Main.java b/podkorytova_yulia_lab_6/app/src/Main.java new file mode 100644 index 0000000..6058ef7 --- /dev/null +++ b/podkorytova_yulia_lab_6/app/src/Main.java @@ -0,0 +1,109 @@ +import java.util.Random; +import java.util.concurrent.*; + +public class Main { + public static void main(String[] args) throws InterruptedException { + for (int i = 1; i < 12; i++) { + System.out.println("Время поиска детерминанта квадратной матрицы размером " + i + "х" + i + ":"); + int[][] matrix = generateMatrix(i); + + long start = System.currentTimeMillis(); + var resultSequential = findDeterminantSequential(matrix); + long end = System.currentTimeMillis(); + long sequentialTime = end - start; + System.out.println("Обычный (последовательный) алгоритм - " + sequentialTime + " мс"); + + int threadCount = 6; + start = System.currentTimeMillis(); + var resultParallel = findDeterminantParallel(matrix, threadCount); + end = System.currentTimeMillis(); + long parallelTime = end - start; + System.out.println("Параллельный алгоритм c " + threadCount + " потоками - " + parallelTime + " мс\n"); + } + } + + public static int[][] generateMatrix(int size) { + int[][] m = new int[size][size]; + Random random = new Random(); + for (int i = 0; i < size; i++) { + for (int j = 0; j < size; j++) { + m[i][j] = random.nextInt(100); + } + } + + return m; + } + + 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; + } + + 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; + } +} \ No newline at end of file diff --git a/podkorytova_yulia_lab_6/images/res.JPG b/podkorytova_yulia_lab_6/images/res.JPG new file mode 100644 index 0000000..7ef09d3 Binary files /dev/null and b/podkorytova_yulia_lab_6/images/res.JPG differ