DAS_2024_1/aleikin_artem_lab_6/DerminantMatrix/Program.cs

119 lines
3.9 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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