119 lines
3.9 KiB
C#
119 lines
3.9 KiB
C#
|
using System;
|
|||
|
using System.Diagnostics;
|
|||
|
using System.Threading.Tasks;
|
|||
|
|
|||
|
class Program
|
|||
|
{
|
|||
|
static void Main(string[] args)
|
|||
|
{
|
|||
|
int[] sizes = { 10, 11, 12 };
|
|||
|
|
|||
|
int maxThreads = 20;
|
|||
|
|
|||
|
foreach (var size in sizes)
|
|||
|
{
|
|||
|
Console.WriteLine($"\nРазмер матрицы: {size}x{size}");
|
|||
|
|
|||
|
// Генерация матрицы
|
|||
|
var matrix = GenerateMatrix(size);
|
|||
|
|
|||
|
// Последовательное нахождение детерминанта
|
|||
|
var stopwatch = Stopwatch.StartNew();
|
|||
|
var detSequential = DeterminantSequential(matrix);
|
|||
|
stopwatch.Stop();
|
|||
|
long timeSequential = stopwatch.ElapsedMilliseconds;
|
|||
|
Console.WriteLine($"Последовательное вычисление: {timeSequential} мс, детерминант = {detSequential}");
|
|||
|
|
|||
|
// Параллельное нахождение детерминанта
|
|||
|
Console.WriteLine("Параллельное вычисление (время выполнения для каждого количества потоков):");
|
|||
|
for (int threads = 1; threads <= maxThreads; threads++)
|
|||
|
{
|
|||
|
stopwatch.Restart();
|
|||
|
var detParallel = DeterminantParallel(matrix, threads);
|
|||
|
stopwatch.Stop();
|
|||
|
long timeParallel = stopwatch.ElapsedMilliseconds;
|
|||
|
Console.WriteLine($"Потоков: {threads} — {timeParallel} мс");
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// Генерация квадратной матрицы размером size x size
|
|||
|
static double[,] GenerateMatrix(int size)
|
|||
|
{
|
|||
|
var random = new Random();
|
|||
|
var matrix = new double[size, size];
|
|||
|
for (int i = 0; i < size; i++)
|
|||
|
for (int j = 0; j < size; j++)
|
|||
|
matrix[i, j] = random.Next(-10, 10);
|
|||
|
return matrix;
|
|||
|
}
|
|||
|
|
|||
|
// Последовательное вычисление детерминанта
|
|||
|
static double DeterminantSequential(double[,] matrix)
|
|||
|
{
|
|||
|
int size = matrix.GetLength(0);
|
|||
|
if (size == 1)
|
|||
|
return matrix[0, 0];
|
|||
|
|
|||
|
if (size == 2)
|
|||
|
return matrix[0, 0] * matrix[1, 1] - matrix[0, 1] * matrix[1, 0];
|
|||
|
|
|||
|
double determinant = 0;
|
|||
|
for (int col = 0; col < size; col++)
|
|||
|
{
|
|||
|
determinant += Math.Pow(-1, col) * matrix[0, col] * DeterminantSequential(Minor(matrix, 0, col));
|
|||
|
}
|
|||
|
return determinant;
|
|||
|
}
|
|||
|
|
|||
|
// Параллельное вычисление детерминанта
|
|||
|
static double DeterminantParallel(double[,] matrix, int threadCount)
|
|||
|
{
|
|||
|
int size = matrix.GetLength(0);
|
|||
|
if (size == 1)
|
|||
|
return matrix[0, 0];
|
|||
|
|
|||
|
if (size == 2)
|
|||
|
return matrix[0, 0] * matrix[1, 1] - matrix[0, 1] * matrix[1, 0];
|
|||
|
|
|||
|
double determinant = 0;
|
|||
|
object lockObject = new object();
|
|||
|
|
|||
|
Parallel.For(0, size, new ParallelOptions { MaxDegreeOfParallelism = threadCount }, col =>
|
|||
|
{
|
|||
|
double minorDeterminant = DeterminantSequential(Minor(matrix, 0, col));
|
|||
|
double term = Math.Pow(-1, col) * matrix[0, col] * minorDeterminant;
|
|||
|
|
|||
|
lock (lockObject)
|
|||
|
{
|
|||
|
determinant += term;
|
|||
|
}
|
|||
|
});
|
|||
|
|
|||
|
return determinant;
|
|||
|
}
|
|||
|
|
|||
|
// Создание минора для матрицы
|
|||
|
static double[,] Minor(double[,] matrix, int row, int col)
|
|||
|
{
|
|||
|
int size = matrix.GetLength(0);
|
|||
|
var minor = new double[size - 1, size - 1];
|
|||
|
|
|||
|
for (int i = 0, minorRow = 0; i < size; i++)
|
|||
|
{
|
|||
|
if (i == row) continue;
|
|||
|
|
|||
|
for (int j = 0, minorCol = 0; j < size; j++)
|
|||
|
{
|
|||
|
if (j == col) continue;
|
|||
|
|
|||
|
minor[minorRow, minorCol] = matrix[i, j];
|
|||
|
minorCol++;
|
|||
|
}
|
|||
|
minorRow++;
|
|||
|
}
|
|||
|
|
|||
|
return minor;
|
|||
|
}
|
|||
|
}
|