Anul 3 Semestrul 1
This commit is contained in:
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user