using System.Diagnostics; internal class Program { private static string[] _resTableColumnsNames = new string[] { "m*m", "1 t", "2 t", "3 t", "4 t", "5 t", "6 t"}; private static void Main(string[] args) { Console.WriteLine(string.Join("\t", _resTableColumnsNames)); for (int i = 8; i < 14; i++) { var e = CreateMatrix(i, i); List<long> times = new() { i }; for (int j = 1; j <= 6; j++) { var sw = new Stopwatch(); sw.Start(); CalculateDeterminant(e, j); sw.Stop(); times.Add(sw.ElapsedMilliseconds); } Console.WriteLine(string.Join("\t", times)); } } private static int[,] CreateMatrix(int x, int y) { var rnd = new Random(); var res = new int[y, x]; for (int i = 0; i < y; i++) { for (int j = 0; j < x; j++) { res[i, j] = rnd.Next(0, 100); } } return res; } private static void PritMatrix(int[,] mx) { for (int i = 0; i < mx.GetLength(0); i++) { for (int j = 0; j < mx.GetLength(1); j++) { Console.Write($"{mx[i, j].ToString("000")}\t"); } Console.WriteLine(); } } public static long CalculateDeterminant(int[,] matrix, int maxThreads) => CalculateDeterminantParalel( matrix, Enumerable.Range(0, matrix.GetLength(0)).ToArray(), Enumerable.Range(0, matrix.GetLength(1)).ToArray(), maxThreads ); private static long CalculateDeterminant(int[,] matrix, int[] rows, int[] columns) { if (rows.Length <= 3) return GetSimpleDeterminant(matrix, rows.ToList(), columns.ToList()); (int fixIndex, bool isFixRow) = GetTheBestRowColumn(matrix, rows, columns); long res = 0; int row = isFixRow ? rows[fixIndex] : -1; int column = isFixRow ? -1 : columns[fixIndex]; for (int index = 0; index < rows.Length; index++) { if (isFixRow) column = columns[index]; else row = rows[index]; res += ((index + fixIndex) % 2 != 0 ? -1 : 1) * matrix[column, row] * CalculateDeterminant(matrix, rows.Where(x => x != row).ToArray(), columns.Where(x => x != column).ToArray()); } return res; } private static long CalculateDeterminantParalel(int[,] matrix, int[] rows, int[] columns, int maxThread) { if (rows.Length <= 3) return GetSimpleDeterminant(matrix, rows.ToList(), columns.ToList()); (int fixIndex, bool isFixRow) = GetTheBestRowColumn(matrix, rows, columns); long res = 0; int row = isFixRow ? rows[fixIndex] : -1; int column = isFixRow ? -1 : columns[fixIndex]; var semaphore = new SemaphoreSlim(maxThread, maxThread); for (int index = 0; index < rows.Length; index++) { if (isFixRow) column = columns[index]; else row = rows[index]; var c_column = column; var c_row = row; var c_index = fixIndex + index; semaphore.Wait(); Task.Run(() => { try { res += (c_index % 2 != 0 ? -1 : 1) * matrix[c_column, c_row] * CalculateDeterminant( matrix, rows.Where(x => x != c_row).ToArray(), columns.Where(x => x != c_column).ToArray() ); } finally { semaphore.Release(); } }); } semaphore.Wait(maxThread); return res; } private static (int fixIndex, bool isFixRow) GetTheBestRowColumn(int[,] matrix, int[] rows, int[] columns) { Dictionary<int, int> zerosCount = rows.Select(x => x + 1).Union(columns.Select(x => -x - 1)).ToDictionary(x => x, x => 0); foreach (var r in rows) { foreach (var c in columns) { if (matrix[r, c] == 0) { zerosCount[r + 1] += 1; zerosCount[-c - 1] += 1; } } } var best = zerosCount.ToList().OrderByDescending(x => x.Value).FirstOrDefault().Key; if (best > 0) { return (Array.IndexOf(rows, best - 1), true); } else { return (Array.IndexOf(columns, -best + 1), false); } } private static long GetSimpleDeterminant(int[,] matrix, List<int> rows, List<int> columns) { if (rows.Count == 1) { return matrix[columns[0], rows[0]]; } else if (rows.Count == 2) { return matrix[columns[0], rows[0]] * matrix[columns[1], rows[1]] - matrix[columns[0], rows[1]] * matrix[columns[1], rows[0]]; } else if (columns.Count == 3) { return matrix[columns[0], rows[0]] * matrix[columns[1], rows[1]] * matrix[columns[2], rows[2]] + matrix[columns[0], rows[1]] * matrix[columns[1], rows[2]] * matrix[columns[2], rows[0]] + matrix[columns[0], rows[2]] * matrix[columns[1], rows[0]] * matrix[columns[2], rows[1]] - matrix[columns[0], rows[2]] * matrix[columns[1], rows[1]] * matrix[columns[2], rows[0]] - matrix[columns[1], rows[0]] * matrix[columns[0], rows[1]] * matrix[columns[2], rows[2]] - matrix[columns[0], rows[0]] * matrix[columns[1], rows[2]] * matrix[columns[2], rows[1]]; } throw new Exception(); } }