diff --git a/kutygin_andrey_lab_5/.idea/workspace.xml b/kutygin_andrey_lab_5/.idea/workspace.xml new file mode 100644 index 0000000..a3e814b --- /dev/null +++ b/kutygin_andrey_lab_5/.idea/workspace.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1704910856218 + + + + \ No newline at end of file diff --git a/kutygin_andrey_lab_6/.idea/.gitignore b/kutygin_andrey_lab_6/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/kutygin_andrey_lab_6/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/kutygin_andrey_lab_6/.idea/jpa-buddy.xml b/kutygin_andrey_lab_6/.idea/jpa-buddy.xml new file mode 100644 index 0000000..966d5f5 --- /dev/null +++ b/kutygin_andrey_lab_6/.idea/jpa-buddy.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/kutygin_andrey_lab_6/.idea/misc.xml b/kutygin_andrey_lab_6/.idea/misc.xml new file mode 100644 index 0000000..cac8158 --- /dev/null +++ b/kutygin_andrey_lab_6/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/kutygin_andrey_lab_6/.idea/modules.xml b/kutygin_andrey_lab_6/.idea/modules.xml new file mode 100644 index 0000000..497c5f4 --- /dev/null +++ b/kutygin_andrey_lab_6/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/kutygin_andrey_lab_6/README.md b/kutygin_andrey_lab_6/README.md new file mode 100644 index 0000000..6e07872 --- /dev/null +++ b/kutygin_andrey_lab_6/README.md @@ -0,0 +1,101 @@ +## Задание + +Кратко: реализовать нахождение детерминанта квадратной матрицы. + +Подробно: в лабораторной работе требуется сделать два алгоритма: обычный и параллельный (задание со * - реализовать это в рамках одного алгоритма). В параллельном алгоритме предусмотреть ручное задание количества потоков (число потоков = 1 как раз и реализует задание со *), каждый из которых будет выполнять нахождение отдельной группы множителей. + +## Ход работы +*** +### Обычный алгоритм + +`private static BigDecimal findDeterminantGauss(double[][] matrix) { +int n = matrix.length; +BigDecimal det = BigDecimal.ONE;` + + for (int i = 0; i < n; i++) { + int maxRow = i; + for (int j = i + 1; j < n; j++) { + if (Math.abs(matrix[j][i]) > Math.abs(matrix[maxRow][i])) { + maxRow = j; + } + } + + if (maxRow != i) { + double[] temp = matrix[i]; + matrix[i] = matrix[maxRow]; + matrix[maxRow] = temp; + + det = det.multiply(BigDecimal.valueOf(-1)); + } + + for (int j = i + 1; j < n; j++) { + double factor = matrix[j][i] / matrix[i][i]; + for (int k = i; k < n; k++) { + matrix[j][k] -= factor * matrix[i][k]; + } + } + } + + for (int i = 0; i < n; i++) { + det = det.multiply(BigDecimal.valueOf(matrix[i][i])); + } + + return det; + } +### Параллельный алгоритм +`private static BigDecimal findDeterminantGaussParallel(double[][] matrix, int threadsCount) { +int n = matrix.length; +final BigDecimal[] det = {BigDecimal.ONE};` + + ExecutorService executor = Executors.newFixedThreadPool(threadsCount); + + for (int i = 0; i < n; i++) { + final int rowIdx = i; + + int maxRow = rowIdx; + for (int j = rowIdx + 1; j < n; j++) { + if (Math.abs(matrix[j][rowIdx]) > Math.abs(matrix[maxRow][rowIdx])) { + maxRow = j; + } + } + + if (maxRow != rowIdx) { + double[] temp = matrix[rowIdx]; + matrix[rowIdx] = matrix[maxRow]; + matrix[maxRow] = temp; + det[0] = det[0].multiply(BigDecimal.valueOf(-1)); + } + executor.execute(() -> { + for (int j = rowIdx + 1; j < n; j++) { + double factor = matrix[j][rowIdx] / matrix[rowIdx][rowIdx]; + for (int k = rowIdx; k < n; k++) { + matrix[j][k] -= factor * matrix[rowIdx][k]; + } + } + }); + det[0] = det[0].multiply(BigDecimal.valueOf(matrix[rowIdx][rowIdx])); + } + + executor.shutdown(); + + try { + executor.awaitTermination(1, TimeUnit.DAYS); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + return det[0]; + } +## Результат +*** +![](img.png) + +Из данного скриншота можно сделать вывод, что нахождение детерминанта для матрицы: + +100х100 - обычный алгоритм работает лучше параллельного, но разница не сказать что значительная + +300х300 - обычный алгоритм работает хуже параллельного, но при добавлении потоков параллельный алгоритм работает чуть хуже + +500х500 - обычный алгоритм работает значительно лучше параллельного, но параллельный начинает показывать себя лучше при увеличении количества потоков (но обычный алгоритм все равно лучше) + +**Видео**: https://disk.yandex.ru/d/BXTTvXU_YwJmMA \ No newline at end of file diff --git a/kutygin_andrey_lab_6/img.png b/kutygin_andrey_lab_6/img.png new file mode 100644 index 0000000..1062eae Binary files /dev/null and b/kutygin_andrey_lab_6/img.png differ diff --git a/kutygin_andrey_lab_6/lab6.iml b/kutygin_andrey_lab_6/lab6.iml new file mode 100644 index 0000000..c90834f --- /dev/null +++ b/kutygin_andrey_lab_6/lab6.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/kutygin_andrey_lab_6/out/production/lab6/Main.class b/kutygin_andrey_lab_6/out/production/lab6/Main.class new file mode 100644 index 0000000..9500359 Binary files /dev/null and b/kutygin_andrey_lab_6/out/production/lab6/Main.class differ diff --git a/kutygin_andrey_lab_6/src/Main.java b/kutygin_andrey_lab_6/src/Main.java new file mode 100644 index 0000000..ee111e1 --- /dev/null +++ b/kutygin_andrey_lab_6/src/Main.java @@ -0,0 +1,122 @@ +import java.math.BigDecimal; +import java.util.Arrays; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +public class Main { + public static double[][] generateMatrix(int n) { + double[][] matrix = new double[n][n]; + + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + matrix[i][j] = Math.round((Math.random() * 5)); + } + } + return matrix; + } + + private static BigDecimal findDeterminantGauss(double[][] matrix) { + int n = matrix.length; + BigDecimal det = BigDecimal.ONE; + + for (int i = 0; i < n; i++) { + int maxRow = i; + for (int j = i + 1; j < n; j++) { + if (Math.abs(matrix[j][i]) > Math.abs(matrix[maxRow][i])) { + maxRow = j; + } + } + + if (maxRow != i) { + double[] temp = matrix[i]; + matrix[i] = matrix[maxRow]; + matrix[maxRow] = temp; + + det = det.multiply(BigDecimal.valueOf(-1)); + } + + for (int j = i + 1; j < n; j++) { + double factor = matrix[j][i] / matrix[i][i]; + for (int k = i; k < n; k++) { + matrix[j][k] -= factor * matrix[i][k]; + } + } + } + + for (int i = 0; i < n; i++) { + det = det.multiply(BigDecimal.valueOf(matrix[i][i])); + } + + return det; + } + + private static BigDecimal findDeterminantGaussParallel(double[][] matrix, int threadsCount) { + int n = matrix.length; + final BigDecimal[] det = {BigDecimal.ONE}; + + ExecutorService executor = Executors.newFixedThreadPool(threadsCount); + + for (int i = 0; i < n; i++) { + final int rowIdx = i; + + int maxRow = rowIdx; + for (int j = rowIdx + 1; j < n; j++) { + if (Math.abs(matrix[j][rowIdx]) > Math.abs(matrix[maxRow][rowIdx])) { + maxRow = j; + } + } + + if (maxRow != rowIdx) { + double[] temp = matrix[rowIdx]; + matrix[rowIdx] = matrix[maxRow]; + matrix[maxRow] = temp; + det[0] = det[0].multiply(BigDecimal.valueOf(-1)); + } + executor.execute(() -> { + for (int j = rowIdx + 1; j < n; j++) { + double factor = matrix[j][rowIdx] / matrix[rowIdx][rowIdx]; + for (int k = rowIdx; k < n; k++) { + matrix[j][k] -= factor * matrix[rowIdx][k]; + } + } + }); + det[0] = det[0].multiply(BigDecimal.valueOf(matrix[rowIdx][rowIdx])); + } + + executor.shutdown(); + + try { + executor.awaitTermination(1, TimeUnit.DAYS); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + return det[0]; + } + + public static void main(String[] args) { + run(100, 1); + run(100, 5); + run(300, 1); + run(300, 5); + run(500, 1); + run(500, 5); + } + + public static void run(int n, int threadCount) { + System.out.println(String.format("Matrix size: %d X %d", n, n)); + double[][] a = generateMatrix(n); + double[][] aClone = Arrays.copyOf(a, n); + + long time = System.currentTimeMillis(); + BigDecimal determinantGauss = findDeterminantGauss(a); + System.out.println("Execution time: " + (System.currentTimeMillis() - time) + "ms"); + + time = System.currentTimeMillis(); + BigDecimal determinantGaussAsync = findDeterminantGaussParallel(aClone, threadCount); + System.out.println("Execution time parallel: " + (System.currentTimeMillis() - time) + "ms, " + + "threads count: " + threadCount); + System.out.println(); + } +} \ No newline at end of file