From 50021c66911270d57a1e615d0c45c256561b398d Mon Sep 17 00:00:00 2001 From: UrOldFriendSoul Date: Tue, 16 Jan 2024 12:25:18 +0400 Subject: [PATCH] kutygin_andrey_lab_6_ready --- kutygin_andrey_lab_5/.idea/workspace.xml | 55 ++++++++ kutygin_andrey_lab_6/.idea/.gitignore | 3 + kutygin_andrey_lab_6/.idea/jpa-buddy.xml | 6 + kutygin_andrey_lab_6/.idea/misc.xml | 9 ++ kutygin_andrey_lab_6/.idea/modules.xml | 8 ++ kutygin_andrey_lab_6/README.md | 101 +++++++++++++++ kutygin_andrey_lab_6/img.png | Bin 0 -> 49890 bytes kutygin_andrey_lab_6/lab6.iml | 11 ++ .../out/production/lab6/Main.class | Bin 0 -> 4744 bytes kutygin_andrey_lab_6/src/Main.java | 122 ++++++++++++++++++ 10 files changed, 315 insertions(+) create mode 100644 kutygin_andrey_lab_5/.idea/workspace.xml create mode 100644 kutygin_andrey_lab_6/.idea/.gitignore create mode 100644 kutygin_andrey_lab_6/.idea/jpa-buddy.xml create mode 100644 kutygin_andrey_lab_6/.idea/misc.xml create mode 100644 kutygin_andrey_lab_6/.idea/modules.xml create mode 100644 kutygin_andrey_lab_6/README.md create mode 100644 kutygin_andrey_lab_6/img.png create mode 100644 kutygin_andrey_lab_6/lab6.iml create mode 100644 kutygin_andrey_lab_6/out/production/lab6/Main.class create mode 100644 kutygin_andrey_lab_6/src/Main.java 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 0000000000000000000000000000000000000000..1062eaef594ed3bca934e82904454378dacf6152 GIT binary patch literal 49890 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

YlvPGryTS3q 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 + + + + + + + + + + \ 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 0000000000000000000000000000000000000000..95003598b116df20023ab504e4fc0be0ee74d9d4 GIT binary patch literal 4744 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 literal 0 HcmV?d00001 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 -- 2.25.1