import java.math.BigDecimal; import java.math.MathContext; import java.math.RoundingMode; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class FastDeterminantCalculator { public static void main(String[] args) { int[] sizes = {100, 300, 500}; int[] threads = {1, 4, 8, 10}; for (int size : sizes) { BigDecimal[][] matrix = generateMatrix(size); for (int threadCount : threads) { long start = System.currentTimeMillis(); BigDecimal determinant = calculateDeterminant(matrix, threadCount); long end = System.currentTimeMillis(); System.out.printf("Matrix size: %dx%d, Threads: %d, Time: %d ms\n", size, size, threadCount, (end - start)); } } } public static BigDecimal[][] generateMatrix(int size) { BigDecimal[][] matrix = new BigDecimal[size][size]; for (int i = 0; i < size; i++) { BigDecimal rowSum = BigDecimal.ZERO; for (int j = 0; j < size; j++) { matrix[i][j] = BigDecimal.valueOf(Math.random() * 10); if (i != j) { rowSum = rowSum.add(matrix[i][j]); } } matrix[i][i] = rowSum.add(BigDecimal.valueOf(Math.random() * 10 + 1)); } return matrix; } public static BigDecimal calculateDeterminant(BigDecimal[][] matrix, int threadCount) { int size = matrix.length; BigDecimal[][] lu = new BigDecimal[size][size]; int[] permutations = new int[size]; ExecutorService executor = Executors.newFixedThreadPool(threadCount); if (!luDecomposition(matrix, lu, permutations, executor)) { executor.shutdown(); return BigDecimal.ZERO; // Матрица вырожденная } executor.shutdown(); BigDecimal determinant = BigDecimal.ONE; for (int i = 0; i < size; i++) { determinant = determinant.multiply(lu[i][i]); if (permutations[i] != i) { determinant = determinant.negate(); // Меняем знак при перестановке } } return determinant; } public static boolean luDecomposition(BigDecimal[][] matrix, BigDecimal[][] lu, int[] permutations, ExecutorService executor) { int size = matrix.length; for (int i = 0; i < size; i++) { System.arraycopy(matrix[i], 0, lu[i], 0, size); permutations[i] = i; } for (int k = 0; k < size; k++) { int pivot = k; for (int i = k + 1; i < size; i++) { if (lu[i][k].abs().compareTo(lu[pivot][k].abs()) > 0) { pivot = i; } } if (lu[pivot][k].abs().compareTo(BigDecimal.valueOf(1e-10)) < 0) { return false; } if (pivot != k) { BigDecimal[] temp = lu[k]; lu[k] = lu[pivot]; lu[pivot] = temp; int tempPerm = permutations[k]; permutations[k] = permutations[pivot]; permutations[pivot] = tempPerm; } CountDownLatch latch = new CountDownLatch(size - k - 1); for (int i = k + 1; i < size; i++) { int row = i; int finalK = k; executor.submit(() -> { MathContext mc = new MathContext(20, RoundingMode.HALF_UP); lu[row][finalK] = lu[row][finalK].divide(lu[finalK][finalK], mc); for (int j = finalK + 1; j < size; j++) { lu[row][j] = lu[row][j].subtract(lu[row][finalK].multiply(lu[finalK][j], mc)); } latch.countDown(); }); } try { latch.await(); } catch (InterruptedException e) { e.printStackTrace(); return false; } } return true; } }