139 lines
4.1 KiB
C#
139 lines
4.1 KiB
C#
using System;
|
||
using System.Diagnostics;
|
||
using System.Threading.Tasks;
|
||
|
||
class Program
|
||
{
|
||
// Вычисление детерминанта методом Гаусса
|
||
public static double SequentialDeterminant(double[,] matrix)
|
||
{
|
||
int n = matrix.GetLength(0);
|
||
double det = 1;
|
||
|
||
for (int i = 0; i < n; i++)
|
||
{
|
||
int pivot = i;
|
||
for (int j = i + 1; j < n; j++)
|
||
{
|
||
if (Math.Abs(matrix[j, i]) > Math.Abs(matrix[pivot, i]))
|
||
pivot = j;
|
||
}
|
||
|
||
if (Math.Abs(matrix[pivot, i]) < 1e-10)
|
||
return 0;
|
||
|
||
if (i != pivot)
|
||
{
|
||
SwapRows(matrix, i, pivot);
|
||
det = -det;
|
||
}
|
||
|
||
det *= matrix[i, i];
|
||
for (int j = i + 1; j < n; j++)
|
||
{
|
||
matrix[i, j] /= matrix[i, i];
|
||
}
|
||
|
||
for (int j = i + 1; j < n; j++)
|
||
{
|
||
for (int k = i + 1; k < n; k++)
|
||
{
|
||
matrix[j, k] -= matrix[j, i] * matrix[i, k];
|
||
}
|
||
}
|
||
}
|
||
|
||
return det;
|
||
}
|
||
|
||
// Вычисление детерминанта с параллельными вычислениями
|
||
public static double ParallelDeterminant(double[,] matrix, int threads = 1)
|
||
{
|
||
int n = matrix.GetLength(0);
|
||
double det = 1;
|
||
|
||
for (int i = 0; i < n; i++)
|
||
{
|
||
int pivot = i;
|
||
for (int j = i + 1; j < n; j++)
|
||
{
|
||
if (Math.Abs(matrix[j, i]) > Math.Abs(matrix[pivot, i]))
|
||
pivot = j;
|
||
}
|
||
|
||
if (Math.Abs(matrix[pivot, i]) < 1e-10)
|
||
return 0;
|
||
|
||
if (i != pivot)
|
||
{
|
||
SwapRows(matrix, i, pivot);
|
||
det = -det;
|
||
}
|
||
|
||
det *= matrix[i, i];
|
||
for (int j = i + 1; j < n; j++)
|
||
{
|
||
matrix[i, j] /= matrix[i, i];
|
||
}
|
||
|
||
Parallel.For(i + 1, n, new ParallelOptions { MaxDegreeOfParallelism = threads }, j =>
|
||
{
|
||
for (int k = i + 1; k < n; k++)
|
||
{
|
||
matrix[j, k] -= matrix[j, i] * matrix[i, k];
|
||
}
|
||
});
|
||
}
|
||
|
||
return det;
|
||
}
|
||
|
||
private static void SwapRows(double[,] matrix, int row1, int row2)
|
||
{
|
||
int n = matrix.GetLength(1);
|
||
for (int i = 0; i < n; i++)
|
||
{
|
||
double temp = matrix[row1, i];
|
||
matrix[row1, i] = matrix[row2, i];
|
||
matrix[row2, i] = temp;
|
||
}
|
||
}
|
||
|
||
// Запуск и замер времени
|
||
public static void Benchmark(int size)
|
||
{
|
||
var random = new Random();
|
||
double[,] matrix = new double[size, size];
|
||
for (int i = 0; i < size; i++)
|
||
for (int j = 0; j < size; j++)
|
||
matrix[i, j] = random.NextDouble();
|
||
|
||
var stopwatch = new Stopwatch();
|
||
|
||
// Обычный алгоритм
|
||
stopwatch.Start();
|
||
double detSeq = SequentialDeterminant((double[,])matrix.Clone());
|
||
stopwatch.Stop();
|
||
Console.WriteLine($"Обычный алгоритм, размер {size}x{size}: {stopwatch.ElapsedMilliseconds} мс");
|
||
|
||
// Параллельный алгоритм с разным количеством потоков
|
||
int[] threadCounts = { 1, 2, 4, 8 };
|
||
foreach (var threads in threadCounts)
|
||
{
|
||
stopwatch.Restart();
|
||
double detPar = ParallelDeterminant((double[,])matrix.Clone(), threads);
|
||
stopwatch.Stop();
|
||
Console.WriteLine($"Параллельный алгоритм, потоки: {threads}, размер {size}x{size}: {stopwatch.ElapsedMilliseconds} мс");
|
||
}
|
||
}
|
||
|
||
public static void Main()
|
||
{
|
||
int[] sizes = { 100, 300, 500 };
|
||
foreach (var size in sizes)
|
||
{
|
||
Benchmark(size);
|
||
}
|
||
}
|
||
}
|