DAS_2024_1/emelyanov_artem_lab_6/DeterminantCalculator.java

81 lines
2.7 KiB
Java

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<Future<Double>> 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<Double> 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;
}
}