Anul 3 Semestrul 1

This commit is contained in:
2025-02-06 20:33:26 +02:00
parent 0b130ee18c
commit 184f3bd92e
313 changed files with 348499 additions and 0 deletions
@@ -0,0 +1,202 @@
using System.Diagnostics;
namespace Lab_5
{
public class Program
{
//Sequential multiplication of two polynomials
//O(n^2)
public static List<int> PolynomialMultiplication(List<int> poly1, List<int> poly2)
{
int m = poly1.Count;
int n = poly2.Count;
List<int> result = new List<int>(new int[m + n - 1]);
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
result[i + j] += poly1[i] * poly2[j];
}
}
return result;
}
//Karatsuba algorithm for polynomial multiplication
public static List<int> AddPolynomials(List<int> poly1, List<int> poly2)
{
int maxLength = Math.Max(poly1.Count, poly2.Count);
List<int> result = new List<int>(new int[maxLength]);
for (int i = 0; i < maxLength; i++)
{
int coef1 = i < poly1.Count ? poly1[i] : 0;
int coef2 = i < poly2.Count ? poly2[i] : 0;
result[i] = coef1 + coef2;
}
return result;
}
public static List<int> SubtractPolynomials(List<int> poly1, List<int> poly2)
{
int maxLength = Math.Max(poly1.Count, poly2.Count);
List<int> result = new List<int>(new int[maxLength]);
for (int i = 0; i < maxLength; i++)
{
int coef1 = i < poly1.Count ? poly1[i] : 0;
int coef2 = i < poly2.Count ? poly2[i] : 0;
result[i] = coef1 - coef2;
}
return result;
}
public static List<int> Karatsuba(List<int> poly1, List<int> poly2)
{
int n = Math.Max(poly1.Count, poly2.Count);
if (n == 1)
{
return new List<int> { poly1[0] * poly2[0] };
}
while (poly1.Count < n) poly1.Add(0);
while (poly2.Count < n) poly2.Add(0);
int half = n / 2;
List<int> low1 = poly1.GetRange(0, half);
List<int> high1 = poly1.GetRange(half, n - half);
List<int> low2 = poly2.GetRange(0, half);
List<int> high2 = poly2.GetRange(half, n - half);
List<int> z0 = Karatsuba(low1, low2);
List<int> z1 = Karatsuba(AddPolynomials(low1, high1), AddPolynomials(low2, high2));
List<int> z2 = Karatsuba(high1, high2);
List<int> result = new List<int>(new int[2 * n - 1]);
for (int i = 0; i < z0.Count; i++) result[i] += z0[i];
List<int> middle = SubtractPolynomials(SubtractPolynomials(z1, z0), z2);
for (int i = 0; i < middle.Count; i++) result[i + half] += middle[i];
for (int i = 0; i < z2.Count; i++) result[i + 2 * half] += z2[i];
return result;
}
//Parallel multiplication of two polynomials
//O(n^2)
public static List<int> ParallelPolynomialMultiplication(List<int> poly1, List<int> poly2)
{
int m = poly1.Count;
int n = poly2.Count;
List<int> result = new List<int>(new int[m + n - 1]);
Parallel.For(0, m, i =>
{
for (int j = 0; j < n; j++)
{
result[i + j] += poly1[i] * poly2[j];
}
});
return result;
}
//Karatsuba algorithm for polynomial multiplication
public static List<int> ParallelKaratsuba(List<int> poly1, List<int> poly2)
{
int n = Math.Max(poly1.Count, poly2.Count);
if (n == 1)
{
return new List<int> { poly1[0] * poly2[0] };
}
while (poly1.Count < n) poly1.Add(0);
while (poly2.Count < n) poly2.Add(0);
int half = n / 2;
List<int> low1 = poly1.GetRange(0, half);
List<int> high1 = poly1.GetRange(half, n - half);
List<int> low2 = poly2.GetRange(0, half);
List<int> high2 = poly2.GetRange(half, n - half);
List<int> z0 = [], z1 = [], z2 = [];
Parallel.Invoke(
() => z0 = ParallelKaratsuba(low1, low2),
() => z1 = ParallelKaratsuba(AddPolynomials(low1, high1), AddPolynomials(low2, high2)),
() => z2 = ParallelKaratsuba(high1, high2)
);
List<int> result = new List<int>(new int[2 * n - 1]);
for (int i = 0; i < z0.Count; i++) result[i] += z0[i];
List<int> middle = SubtractPolynomials(SubtractPolynomials(z1, z0), z2);
for (int i = 0; i < middle.Count; i++) result[i + half] += middle[i];
for (int i = 0; i < z2.Count; i++) result[i + 2 * half] += z2[i];
return result;
}
public static void Main(string[] args)
{
int degree = 999;
Random random = new Random();
// Generate Polynomial 1
List<int> poly1 = new List<int>();
for (int i = 0; i <= degree; i++)
{
poly1.Add(random.Next(-100, 101));
}
// Generate Polynomial 2
List<int> poly2 = new List<int>();
for (int i = 0; i <= degree; i++)
{
poly2.Add(random.Next(-100, 101));
}
//Console.WriteLine("Polynomial 1: " + string.Join(" ", poly1));
//Console.WriteLine("Polynomial 2: " + string.Join(" ", poly2));
Stopwatch timer = new Stopwatch();
timer.Start();
List<int> result = PolynomialMultiplication(poly1, poly2);
timer.Stop();
//Console.WriteLine("Result O(n) sequencial: " + string.Join(" ", result));
Console.WriteLine("Time: " + timer.ElapsedMilliseconds + "ms");
timer.Start();
result = Karatsuba(poly1, poly2);
timer.Stop();
//Console.WriteLine("Result Karatsuba sequencial: " + string.Join(" ", result));
Console.WriteLine("Time: " + timer.ElapsedMilliseconds + "ms");
timer.Start();
result = ParallelPolynomialMultiplication(poly1, poly2);
timer.Stop();
//Console.WriteLine("Result O(n) parallel: " + string.Join(" ", result));
Console.WriteLine("Time: " + timer.ElapsedMilliseconds + "ms");
timer.Start();
result = ParallelKaratsuba(poly1, poly2);
timer.Stop();
//Console.WriteLine("Result Karatsuba parallel: " + string.Join(" ", result));
Console.WriteLine("Time: " + timer.ElapsedMilliseconds + "ms");
}
}
}