Merge pull request 'belyaeva lab6 ready' (#116) from belyaeva_ekaterina_lab_6 into main
Reviewed-on: http://student.git.athene.tech/Alexey/DAS_2023_1/pulls/116
This commit is contained in:
commit
b3c9d6a471
29
belyaeva_ekaterina_lab_6/.gitignore
vendored
Normal file
29
belyaeva_ekaterina_lab_6/.gitignore
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
### IntelliJ IDEA ###
|
||||
out/
|
||||
!**/src/main/**/out/
|
||||
!**/src/test/**/out/
|
||||
|
||||
### Eclipse ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
bin/
|
||||
!**/src/main/**/bin/
|
||||
!**/src/test/**/bin/
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
||||
|
||||
### Mac OS ###
|
||||
.DS_Store
|
105
belyaeva_ekaterina_lab_6/README.md
Normal file
105
belyaeva_ekaterina_lab_6/README.md
Normal file
@ -0,0 +1,105 @@
|
||||
# Лабораторная работа №6
|
||||
|
||||
## Задание
|
||||
|
||||
Кратко: реализовать нахождение детерминанта квадратной матрицы.
|
||||
|
||||
Подробно: в лабораторной работе требуется сделать два алгоритма: обычный и параллельный. В параллельном алгоритме предусмотреть ручное задание количества потоков, каждый из которых будет выполнять нахождение отдельной группы множителей.
|
||||
## Ход работы
|
||||
|
||||
### Обычный алгоритм
|
||||
```
|
||||
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];
|
||||
}
|
||||
```
|
||||
|
||||
## Результат
|
||||
|
||||
Была проверка времени выполнения алгоритма для матриц размером 100х100, 300х300, 500х500 с разным количеством потоков.
|
||||
|
||||
![img.png](img.png)
|
||||
|
||||
Из данного скриншота можно сделать вывод, что нахождение детерминанта для матрицы:
|
||||
- 100х100 - обычный алгоритм работает лучше параллельного, но разница не сказать что значительная
|
||||
- 300х300 - обычный алгоритм работает хуже параллельного, но при добавлении потоков параллельный алгоритм работает чуть хуже
|
||||
- 500х500 - обычный алгоритм работает значительно лучше параллельного, но параллельный начинает показывать себя лучше при увеличении количества потоков (но обычный алгоритм все равно лучше)
|
||||
|
||||
Работоспособность показана в видео: [lab6.mp4](lab6.mp4)
|
BIN
belyaeva_ekaterina_lab_6/img.png
Normal file
BIN
belyaeva_ekaterina_lab_6/img.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 62 KiB |
BIN
belyaeva_ekaterina_lab_6/lab6.mp4
Normal file
BIN
belyaeva_ekaterina_lab_6/lab6.mp4
Normal file
Binary file not shown.
123
belyaeva_ekaterina_lab_6/src/Main.java
Normal file
123
belyaeva_ekaterina_lab_6/src/Main.java
Normal file
@ -0,0 +1,123 @@
|
||||
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("Размер матрицы: %d х %d", n, n));
|
||||
double[][] a = generateMatrix(n);
|
||||
double[][] aClone = Arrays.copyOf(a, n);
|
||||
|
||||
long time = System.currentTimeMillis();
|
||||
BigDecimal determinantGauss = findDeterminantGauss(a);
|
||||
System.out.println("Время выполнения: " + (System.currentTimeMillis() - time) + "ms");
|
||||
|
||||
time = System.currentTimeMillis();
|
||||
BigDecimal determinantGaussAsync = findDeterminantGaussParallel(aClone, threadCount);
|
||||
System.out.println("Время параллельного выполнения: " + (System.currentTimeMillis() - time) + "ms, " +
|
||||
"количество потоков: " + threadCount);
|
||||
System.out.println();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user