Merge pull request 'podkorytova_yulia_lab_6 is ready' (#108) from podkorytova_yulia_lab_6 into main
Reviewed-on: http://student.git.athene.tech/Alexey/DAS_2023_1/pulls/108
This commit is contained in:
commit
4e177372a9
100
podkorytova_yulia_lab_6/README.md
Normal file
100
podkorytova_yulia_lab_6/README.md
Normal file
@ -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
|
109
podkorytova_yulia_lab_6/app/src/Main.java
Normal file
109
podkorytova_yulia_lab_6/app/src/Main.java
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
}
|
BIN
podkorytova_yulia_lab_6/images/res.JPG
Normal file
BIN
podkorytova_yulia_lab_6/images/res.JPG
Normal file
Binary file not shown.
After Width: | Height: | Size: 83 KiB |
Loading…
Reference in New Issue
Block a user