diff --git a/emelyanov_artem_lab_6/Benchmark.java b/emelyanov_artem_lab_6/Benchmark.java new file mode 100644 index 0000000..1c038e5 --- /dev/null +++ b/emelyanov_artem_lab_6/Benchmark.java @@ -0,0 +1,27 @@ +import java.util.concurrent.ExecutionException; + +public class Benchmark { + public static void main(String[] args) throws ExecutionException, InterruptedException { + int[] sizes = {5, 7, 10}; + + for (int size : sizes) { + int[][] matrix = MatrixGenerator.generateMatrix(size); + + // Последовательное вычисление + long startSequential = System.nanoTime(); + double detSequential = DeterminantCalculator.calculateDeterminant(matrix, 1); + long endSequential = System.nanoTime(); + System.out.println("Последовательно (" + size + "x" + size + "): " + (endSequential - startSequential) / 1_000_000 + " ms, детерминант: " + detSequential); + + // Параллельное вычисление + for (int numThreads : new int[]{2, 4, 8}) { + long startParallel = System.nanoTime(); + double detParallel = DeterminantCalculator.calculateDeterminant(matrix, numThreads); + long endParallel = System.nanoTime(); + System.out.println("Параллельно (" + size + "x" + size + ", " + numThreads + " потоков): " + + (endParallel - startParallel) / 1_000_000 + " ms, детерминант: " + detParallel); + } + System.out.println("--------------------------------------------------"); + } + } +} diff --git a/emelyanov_artem_lab_6/DeterminantCalculator.java b/emelyanov_artem_lab_6/DeterminantCalculator.java new file mode 100644 index 0000000..1c41c38 --- /dev/null +++ b/emelyanov_artem_lab_6/DeterminantCalculator.java @@ -0,0 +1,80 @@ +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; + +public class DeterminantCalculator { + public static int calculateDeterminant(int[][] matrix, int numThreads) throws InterruptedException, ExecutionException { + int size = matrix.length; + + // Если размер матрицы 1x1, возвращаем единственный элемент. + if (size == 1) { + return matrix[0][0]; + } + + // Если количество потоков равно 1, выполняем последовательный алгоритм. + if (numThreads == 1) { + return sequentialDeterminant(matrix); + } + + // Иначе выполняем параллельный алгоритм. + return parallelDeterminant(matrix, numThreads); + } + + private static int sequentialDeterminant(int[][] matrix) { + int size = matrix.length; + if (size == 1) { + return matrix[0][0]; + } + if (size == 2) { + return matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0]; + } + + int determinant = 0; + for (int col = 0; col < size; col++) { + determinant += (int) (Math.pow(-1, col) * matrix[0][col] * sequentialDeterminant(getMinor(matrix, 0, col))); + } + return determinant; + } + + private static int parallelDeterminant(int[][] matrix, int numThreads) throws InterruptedException, ExecutionException { + int size = matrix.length; + ExecutorService executor = Executors.newFixedThreadPool(numThreads); + List> futures = new ArrayList<>(); + + for (int col = 0; col < size; col++) { + int finalCol = col; + futures.add(executor.submit(() -> { + double minorDet = sequentialDeterminant(getMinor(matrix, 0, finalCol)); + return Math.pow(-1, finalCol) * matrix[0][finalCol] * minorDet; + })); + } + + int determinant = 0; + for (Future future : futures) { + determinant += future.get(); + } + + executor.shutdown(); + return determinant; + } + + private static int[][] getMinor(int[][] matrix, int row, int col) { + int size = matrix.length; + int[][] minor = new int[size - 1][size - 1]; + + for (int i = 0, mi = 0; i < size; i++) { + if (i == row) continue; + for (int j = 0, mj = 0; j < size; j++) { + if (j == col) continue; + minor[mi][mj] = matrix[i][j]; + mj++; + } + mi++; + } + return minor; + } +} + diff --git a/emelyanov_artem_lab_6/MatrixGenerator.java b/emelyanov_artem_lab_6/MatrixGenerator.java new file mode 100644 index 0000000..3baecd7 --- /dev/null +++ b/emelyanov_artem_lab_6/MatrixGenerator.java @@ -0,0 +1,11 @@ +public class MatrixGenerator { + public static int[][] generateMatrix(int size) { + int[][] matrix = new int[size][size]; + for (int i = 0; i < size; i++) { + for (int j = 0; j < size; j++) { + matrix[i][j] = (int) (Math.random() * 100); + } + } + return matrix; + } +} diff --git a/emelyanov_artem_lab_6/Readme.md b/emelyanov_artem_lab_6/Readme.md new file mode 100644 index 0000000..162d74e --- /dev/null +++ b/emelyanov_artem_lab_6/Readme.md @@ -0,0 +1,12 @@ +# Поиск детерминанта + +Данная работа посвящена реализации и сравнению последовательного и параллельного алгоритмов поиска детерминанта матриц на языке Java. Целью является оценка производительности при использовании разного числа потоков. + +## Результаты: + +![img.png](images/img.png) + +Как видим, однозначно сказать нельзя, для маленьких матриц многопоточность особо не повлияла. Начиная с матрицы размерностью 10, есть прибавка в производительности. Посмотрим на сложность алгоритма, и она будет что-то около O(n!), так как алгоритм рекурсивный. +Для больших матриц, типа 100 на 100, сложность будет огромной, и не думаю что такое получится посчитать. + +Ссылка на видео: https://drive.google.com/file/d/1eCNcSLLLfWGlOk5Z0y0CfOfkbxeASrdE/view?usp=sharing \ No newline at end of file diff --git a/emelyanov_artem_lab_6/images/img.png b/emelyanov_artem_lab_6/images/img.png new file mode 100644 index 0000000..52abf13 Binary files /dev/null and b/emelyanov_artem_lab_6/images/img.png differ diff --git a/emelyanov_artem_lab_6/img.png b/emelyanov_artem_lab_6/img.png new file mode 100644 index 0000000..52abf13 Binary files /dev/null and b/emelyanov_artem_lab_6/img.png differ diff --git a/emelyanov_artem_lab_7/.idea/workspace.xml b/emelyanov_artem_lab_7/.idea/workspace.xml new file mode 100644 index 0000000..b8c6381 --- /dev/null +++ b/emelyanov_artem_lab_7/.idea/workspace.xml @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 1729344698203 + + + + + + + + + + \ No newline at end of file