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,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<RootNamespace>Lab_5</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
@@ -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");
}
}
}
@@ -0,0 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<RootNamespace>Lab_6</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
@@ -0,0 +1,92 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
class HamiltonianCycleFinder
{
private readonly int[,] graph;
private readonly int n;
private volatile List<int>? result = null;
public HamiltonianCycleFinder(int[,] graph)
{
this.graph = graph;
this.n = graph.GetLength(0);
}
public List<int>? FindHamiltonianCycle(int startVertex)
{
var path = new List<int> { startVertex };
var visited = new bool[n];
visited[startVertex] = true;
FindCycleParallel(startVertex, path, visited);
return result;
}
private void FindCycleParallel(int currentVertex, List<int> path, bool[] visited)
{
if (result != null) return;
if (path.Count == n)
{
if (graph[currentVertex, path[0]] == 1)
{
lock (this)
{
if (result == null)
{
result = new List<int>(path) { path[0] };
}
}
}
return;
}
Parallel.For(0, n, i =>
{
if (graph[currentVertex, i] == 1 && !visited[i] && result == null)
{
var newVisited = new bool[visited.Length];
Array.Copy(visited, newVisited, visited.Length);
newVisited[i] = true;
var newPath = new List<int>(path) { i };
FindCycleParallel(i, newPath, newVisited);
}
});
}
static void Main(string[] args)
{
//int[,] graph = {
// { 0, 1, 1, 0 },
// { 1, 0, 1, 1 },
// { 1, 1, 0, 1 },
// { 0, 1, 1, 0 }
//};
int[,] graph = {
{ 0, 0, 0, 0 },
{ 0, 0, 1, 1 },
{ 0, 1, 0, 1 },
{ 0, 1, 1, 0 }
};
var finder = new HamiltonianCycleFinder(graph);
int startVertex = 0;
var cycle = finder.FindHamiltonianCycle(startVertex);
if (cycle != null)
{
Console.WriteLine("Hamiltonian Cycle found:");
Console.WriteLine(string.Join(" -> ", cycle));
}
else
{
Console.WriteLine("No Hamiltonian Cycle exists.");
}
}
}
@@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<RootNamespace>Lab_7</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<EnableUnsafeBinaryFormatterSerialization>true</EnableUnsafeBinaryFormatterSerialization>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MPI.NET" Version="1.4.0" />
</ItemGroup>
</Project>
@@ -0,0 +1,208 @@
using MPI;
using System;
using System.Diagnostics;
class PolynomialMultiplication
{
static void Main(string[] args)
{
// mpiexec.exe -n 4 "Lab 7.exe"
MPI.Environment.Run(ref args, communicator =>
{
int rank = communicator.Rank;
int size = communicator.Size;
List<int> poly1 = [3, 2, 1];
List<int> poly2 = [1, 0, -1 ];
Console.WriteLine($"Rank: {rank}, Size: {size}");
if (rank == 0)
{
Console.WriteLine($"Polynomial 1: {string.Join(", ", poly1)}");
Console.WriteLine($"Polynomial 2: {string.Join(", ", poly2)}");
}
communicator.Broadcast(ref poly1, 0);
communicator.Broadcast(ref poly2, 0);
if (rank == 0)
Console.WriteLine("\nStarting Regular Multiplication...");
Stopwatch stopwatch = Stopwatch.StartNew();
List<int> resultRegular = PerformRegularMultiplication(communicator, poly1, poly2);
stopwatch.Stop();
if (rank == 0)
{
Console.WriteLine("Regular Multiplication Result: " + string.Join(", ", resultRegular));
Console.WriteLine($"Regular Multiplication Time: {stopwatch.Elapsed.TotalSeconds} seconds\n");
}
if (rank == 0)
Console.WriteLine("Starting Karatsuba Multiplication...");
stopwatch.Restart();
List<int> resultKaratsuba = KaratsubaMain(communicator, poly1, poly2);
stopwatch.Stop();
if (rank == 0)
{
Console.WriteLine("Karatsuba Multiplication Result: " + string.Join(", ", resultKaratsuba));
Console.WriteLine($"Karatsuba Multiplication Time: {stopwatch.Elapsed.TotalSeconds} seconds");
}
});
}
static List<int> PerformRegularMultiplication(Intracommunicator communicator, List<int> poly1, List<int> poly2)
{
int rank = communicator.Rank;
int size = communicator.Size;
int resultSize = poly1.Count + poly2.Count - 1;
int chunkSize = poly1.Count / size;
int start = rank * chunkSize;
int end = (rank == size - 1) ? poly1.Count : start + chunkSize;
List<int> localResult = [];
localResult.AddRange(new int[resultSize]);
for (int i = start; i < end; i++)
{
for (int j = 0; j < poly2.Count; j++)
{
localResult[i + j] += poly1[i] * poly2[j];
}
}
List<int> finalResult = [];
finalResult.AddRange(new int[resultSize]);
for (int i = 0; i < resultSize; i++)
{
int localValue = localResult[i];
int reducedValue = communicator.Reduce(localValue, Operation<int>.Add, 0);
if (rank == 0)
{
finalResult[i] = reducedValue;
}
}
return finalResult;
}
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;
}
public static List<int> KaratsubaMain(Intracommunicator communicator, List<int> poly1, List<int> poly2)
{
int rank = communicator.Rank;
int size = communicator.Size;
int n = Math.Max(poly1.Count, poly2.Count);
List<int> result = new List<int>(new int[2 * n - 1]);
if (rank == 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);
// Distribute tasks
communicator.Send(low1, 1, 0);
communicator.Send(low2, 1, 1);
communicator.Send(AddPolynomials(low1, high1), 2, 0);
communicator.Send(AddPolynomials(low2, high2), 2, 1);
communicator.Send(high1, 3, 0);
communicator.Send(high2, 3, 1);
// Collect results
List<int> z0 = communicator.Receive<List<int>>(1, 0);
List<int> z1 = communicator.Receive<List<int>>(2, 0);
List<int> z2 = communicator.Receive<List<int>>(3, 0);
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];
}
else
{
// Worker processes
List<int> poly1Part = communicator.Receive<List<int>>(0, 0);
List<int> poly2Part = communicator.Receive<List<int>>(0, 1);
List<int> resultWorker = Karatsuba(poly1Part, poly2Part);
communicator.Send(resultWorker, 0, 0);
}
return result;
}
}
@@ -0,0 +1,7 @@
{
"runtimeOptions": {
"configProperties": {
"System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": true
}
}
}
@@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
@@ -0,0 +1,182 @@
using System.Diagnostics;
using System.Threading.Tasks;
namespace Lab1
{
// Represents a lock for an integer value
public class IntLock
{
public int Value { get; set; }
}
// Represents the type of operation (Add or Subtract)
public enum OperationType
{
Add,
Subtract
}
// Represents an operation performed on an account
public class Operation
{
public int SerialNumber { get; set; }
public OperationType Type { get; set; }
public int Amount { get; set; }
public int From { get; set; }
}
// Represents a bank account
public class Account
{
public int Id { get; set; }
public int Balance { get; set; }
public List<Operation> Operations { get; set; } = new List<Operation>();
}
// Represents a bank
public class Bank
{
public int NumberOfAccounts { get; } = 20;
public List<Account> Accounts { get; set; } = new List<Account>();
private IntLock serialNumber = new IntLock { Value = 0 };
// Initializes the bank with accounts
public Bank()
{
for (int i = 0; i < NumberOfAccounts; i++)
{
Accounts.Add(new Account { Balance = 10000, Id = i });
}
}
// Transfers a specified amount from one account to another
public void Transfer(int from, int to, int amount, int? threadNumber = null)
{
int transferSerialNumber;
lock (serialNumber)
{
transferSerialNumber = serialNumber.Value;
serialNumber.Value = serialNumber.Value + 1;
}
var firstLocked = from < to ? Accounts[from] : Accounts[to];
var secondLocked = from < to ? Accounts[to] : Accounts[from];
lock (firstLocked)
{
lock (secondLocked)
{
if (Accounts[from].Balance < amount)
{
Console.WriteLine("Not enough money");
return;
}
Accounts[from].Balance -= amount;
Accounts[to].Balance += amount;
Accounts[from].Operations.Add(new Operation { SerialNumber = transferSerialNumber, Type = OperationType.Subtract, Amount = amount, From = to });
Accounts[to].Operations.Add(new Operation { SerialNumber = transferSerialNumber, Type = OperationType.Add, Amount = amount, From = from });
Console.WriteLine($"Transfered {amount} from {from} to {to} - Serial Number: {transferSerialNumber} {threadNumber}");
Thread.Sleep(100);
}
}
}
// Performs a consistency check on the accounts
public void ConsistencyCheck()
{
List<object> enteredLocks = new List<object>();
try
{
foreach (var account in Accounts)
{
Monitor.Enter(account);
enteredLocks.Add(account);
}
foreach (var account in Accounts)
{
var balance = 10000;
foreach (var operation in account.Operations)
{
if (operation.Type == OperationType.Add)
{
balance += operation.Amount;
}
else
{
balance -= operation.Amount;
}
var hasRecipient = Accounts[operation.From].Operations.Any(op => op.SerialNumber == operation.SerialNumber);
if (!hasRecipient)
{
Console.WriteLine($"Inconsistency found in account {account.Id}");
}
}
if (balance != account.Balance)
{
Console.WriteLine($"Inconsistency found in account {account.Id}");
}
}
}
finally
{
foreach (var lockObject in enteredLocks)
{
Monitor.Exit(lockObject);
}
}
Console.WriteLine("Consistency check finished");
}
// Performs a specified number of random transfers between accounts
public void PerformNRandomTransfers(int n, int threadNumber, bool consistencyCheck = false)
{
for (int i = 0; i < n; i++)
{
var from = (new Random()).Next(0, NumberOfAccounts);
int to;
while ((to = (new Random()).Next(0, NumberOfAccounts)) == from) ;
var amount = (new Random()).Next(10, 100);
Transfer(from, to, amount, threadNumber);
if (consistencyCheck && i % 20 == 0)
{
ConsistencyCheck();
}
}
}
}
// Represents the entry point of the program
public class Program
{
public static void Main(string[] args)
{
var bank = new Bank();
var numberOfThreads = 10;
var tasks = new List<Task>();
var timer = new Stopwatch();
timer.Start();
for (int i = 0; i < numberOfThreads; i++)
{
var iCopy = i;
tasks.Add(Task.Run(() => bank.PerformNRandomTransfers(10, iCopy, true)));
}
Task.WaitAll(tasks.ToArray());
timer.Stop();
Console.WriteLine($"Execution time: {timer.ElapsedMilliseconds}");
bank.ConsistencyCheck();
}
}
}
@@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
@@ -0,0 +1,60 @@
namespace Lab2
{
public class Program
{
private static List<int> vectorA = [ 2, 4, 6, 8 ];
private static List<int> vectorB = [ 5, 6, 7, 8 ];
private static List<int> producs = [];
private static int scalarProduct = 0;
private static readonly object locker = new object();
public static void Main()
{
Thread producer = new Thread(Produce);
Thread consumer = new Thread(Consume);
producer.Start();
consumer.Start();
producer.Join();
consumer.Join();
Console.WriteLine($"Scalar Product: {scalarProduct}");
}
public static void Produce()
{
int index = 0;
while (index < vectorA.Count)
{
lock (locker)
{
producs.Add(vectorA[index] * vectorB[index]);
Console.WriteLine($"Produced: {producs[index]}");
Monitor.Pulse(locker);
Thread.Sleep(1000);
index++;
}
}
}
public static void Consume()
{
int index = 0;
while (index < vectorA.Count)
{
lock (locker)
{
while (index >= producs.Count)
{
Monitor.Wait(locker);
}
scalarProduct += producs[index];
Console.WriteLine($"Consumed: {producs[index]}");
index++;
}
}
}
}
}
@@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
@@ -0,0 +1,90 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Lab3
{
public class Matrix
{
public List<List<int>> result = [];
public Matrix(int size)
{
for (int i = 0; i < size; i++)
{
result.Add(new List<int>());
for (int j = 0; j < size; j++)
{
result[i].Add(0);
}
}
}
public int MatrixCellProduct(List<List<int>> A, List<List<int>> B, int i, int j)
{
int N = A.Count;
int result = 0;
for (int k = 0; k < N; k++)
{
result += A[i][k] * B[k][j];
}
return result;
}
public void MatrixProduct(List<List<int>> A, List<List<int>> B, int numberOfThreads, int threadIndex)
{
int N = A.Count;
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
if ((i + j) % numberOfThreads == threadIndex)
{
result[i][j] = MatrixCellProduct(A, B, i, j);
}
}
}
}
public void MatrixProductUsingThreads(List<List<int>> A, List<List<int>> B, int numberOfThreads)
{
List<Thread> threads = new List<Thread>();
for (int i = 0; i < numberOfThreads; i++)
{
int threadIndex = i;
Thread thread = new Thread(() => MatrixProduct(A, B, numberOfThreads, threadIndex));
threads.Add(thread);
thread.Start();
}
for (int i = 0; i < numberOfThreads; i++)
{
threads[i].Join();
}
}
public void MatrixProductUsingThreadPool(List<List<int>> A, List<List<int>> B, int numberOfTasks)
{
var toProcess = numberOfTasks;
ThreadPool.SetMinThreads(4, 4);
using (ManualResetEvent resetEvent = new ManualResetEvent(false))
{
for (int i = 0; i < numberOfTasks; i++)
{
int threadIndex = i;
ThreadPool.QueueUserWorkItem((state) => {
MatrixProduct(A, B, numberOfTasks, threadIndex);
if (Interlocked.Decrement(ref toProcess) == 0)
resetEvent.Set();
});
}
resetEvent.WaitOne();
}
}
}
}
@@ -0,0 +1,41 @@
using System.Diagnostics;
namespace Lab3
{
public class Program
{
public static void Main(string[] args)
{
List<List<int>> A = new List<List<int>>()
{
new List<int> { 1, 2, 3 },
new List<int> { 4, 5, 6 },
new List<int> { 7, 8, 9 }
};
List<List<int>> B = new List<List<int>>()
{
new List<int> { 9, 8, 7 },
new List<int> { 6, 5, 4 },
new List<int> { 3, 2, 1 }
};
var matrix = new Matrix(A.Count);
var timer = new Stopwatch();
timer.Start();
//matrix.MatrixProductUsingThreads(A, B, 4);
matrix.MatrixProductUsingThreadPool(A, B, 4);
timer.Stop();
Console.WriteLine($"Time elapsed: {timer.ElapsedMilliseconds} ms");
foreach (var row in matrix.result)
{
Console.WriteLine(string.Join(" ", row));
}
}
}
}
@@ -0,0 +1,81 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace Lab4
{
public class AsyncAwait
{
public async Task RunAsync()
{
var ipHostInfo = Dns.GetHostEntry(SocketInfo.Host);
var ipAddress = ipHostInfo.AddressList[0];
var remoteEP = new IPEndPoint(ipAddress, SocketInfo.Port);
var socket = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
var socketInfo = new SocketInfo(socket);
await Connect(socketInfo, remoteEP);
await Send(socketInfo.socket);
await Receive(socketInfo.socket);
socket.Shutdown(SocketShutdown.Both);
}
public Task<Socket> Connect(SocketInfo socketInfo, IPEndPoint endPoint)
{
var tcs = new TaskCompletionSource<Socket>();
socketInfo.socket.BeginConnect(endPoint, ar =>
{
socketInfo.socket.EndConnect(ar);
Console.WriteLine("Socket connected to {0}", socketInfo.socket.RemoteEndPoint.ToString());
tcs.SetResult(socketInfo.socket);
}, null);
return tcs.Task;
}
public Task<Socket> Send(Socket socket)
{
var tcs = new TaskCompletionSource<Socket>();
var request = Encoding.ASCII.GetBytes("GET / HTTP/1.1\r\nHost: " + SocketInfo.Host + "\r\nConnection: close\r\n\r\n");
socket.BeginSend(request, 0, request.Length, 0, ar =>
{
var bytesSent = socket.EndSend(ar);
Console.WriteLine("Sent {0} bytes to server.", bytesSent);
tcs.SetResult(socket);
}, null);
return tcs.Task;
}
public Task<SocketInfo> Receive(Socket socket, SocketInfo socketInfo, TaskCompletionSource<SocketInfo> tcs)
{
socket.BeginReceive(socketInfo.Buffer, 0, SocketInfo.BufferSize, 0, ar =>
{
var bytesRead = socket.EndReceive(ar);
if (bytesRead > 0)
{
socketInfo.Response.Append(Encoding.ASCII.GetString(socketInfo.Buffer, 0, bytesRead));
Receive(socket, socketInfo, tcs);
}
else
{
if (socketInfo.Response.Length > 1)
{
Console.WriteLine("Response: {0}", socketInfo.Response);
}
tcs.SetResult(socketInfo);
}
}, null);
return tcs.Task;
}
public Task<SocketInfo> Receive(Socket socket)
{
var tcs = new TaskCompletionSource<SocketInfo>();
Receive(socket, new SocketInfo(socket), tcs);
return tcs.Task;
}
}
}
@@ -0,0 +1,64 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace Lab4
{
public class DirectCallbacks
{
public void Run()
{
var ipHostInfo = Dns.GetHostEntry(SocketInfo.Host);
var ipAddress = ipHostInfo.AddressList[0];
var remoteEP = new IPEndPoint(ipAddress, SocketInfo.Port);
var socket = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
var socketInfo = new SocketInfo(socket);
socket.BeginConnect(remoteEP, ConnectCallback, socketInfo);
socketInfo.done.WaitOne();
socket.Shutdown(SocketShutdown.Both);
socket.Close();
}
public void ConnectCallback(IAsyncResult ar)
{
var socketInfo = (SocketInfo)ar.AsyncState;
socketInfo.socket.EndConnect(ar);
Console.WriteLine("Socket connected to {0}", socketInfo.socket.RemoteEndPoint.ToString());
var request = Encoding.ASCII.GetBytes("GET / HTTP/1.1\r\nHost: " + SocketInfo.Host + "\r\nConnection: close\r\n\r\n");
socketInfo.socket.BeginSend(request, 0, request.Length, 0, SendCallback, socketInfo);
}
public void SendCallback(IAsyncResult ar)
{
var socketInfo = (SocketInfo)ar.AsyncState;
var bytesSent = socketInfo.socket.EndSend(ar);
Console.WriteLine("Sent {0} bytes to server.", bytesSent);
socketInfo.socket.BeginReceive(socketInfo.Buffer, 0, SocketInfo.BufferSize, 0, ReceiveCallback, socketInfo);
}
public void ReceiveCallback(IAsyncResult ar)
{
var socketInfo = (SocketInfo)ar.AsyncState;
var bytesRead = socketInfo.socket.EndReceive(ar);
if (bytesRead > 0)
{
socketInfo.Response.Append(Encoding.ASCII.GetString(socketInfo.Buffer, 0, bytesRead));
socketInfo.socket.BeginReceive(socketInfo.Buffer, 0, SocketInfo.BufferSize, 0, ReceiveCallback, socketInfo);
}
else
{
if (socketInfo.Response.Length > 1)
{
Console.WriteLine("Response: {0}", socketInfo.Response);
}
socketInfo.done.Set();
}
}
}
}
@@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
@@ -0,0 +1,17 @@
namespace Lab4
{
public class Program
{
public async static Task Main(string[] args)
{
//var directCallbacks = new DirectCallbacks();
//directCallbacks.Run();
//var taskCallbacks = new TaskCallbacks();
//taskCallbacks.Run();
var asyncAwait = new AsyncAwait();
await asyncAwait.RunAsync();
}
}
}
@@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace Lab4
{
public class SocketInfo
{
public const string Host = "www.test.com";
public const int Port = 80;
public const int BufferSize = 1024;
public readonly byte[] Buffer = new byte[BufferSize];
public StringBuilder Response = new StringBuilder();
public readonly Socket socket;
public ManualResetEvent done = new ManualResetEvent(false);
public SocketInfo(Socket socket)
{
this.socket = socket;
}
}
}
@@ -0,0 +1,81 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace Lab4
{
public class TaskCallbacks
{
public void Run()
{
var ipHostInfo = Dns.GetHostEntry(SocketInfo.Host);
var ipAddress = ipHostInfo.AddressList[0];
var remoteEP = new IPEndPoint(ipAddress, SocketInfo.Port);
var socket = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
var socketInfo = new SocketInfo(socket);
var task = Connect(socketInfo, remoteEP).ContinueWith((Task<Socket> socket) => Send(socket.Result)).Unwrap().ContinueWith((Task<Socket> socket) => Receive(socket.Result)).Unwrap();
task.Wait();
socket.Shutdown(SocketShutdown.Both);
}
public Task<Socket> Connect(SocketInfo socketInfo, IPEndPoint endPoint)
{
var tcs = new TaskCompletionSource<Socket>();
socketInfo.socket.BeginConnect(endPoint, ar =>
{
socketInfo.socket.EndConnect(ar);
Console.WriteLine("Socket connected to {0}", socketInfo.socket.RemoteEndPoint.ToString());
tcs.SetResult(socketInfo.socket);
}, null);
return tcs.Task;
}
public Task<Socket> Send(Socket socket)
{
var tcs = new TaskCompletionSource<Socket>();
var request = Encoding.ASCII.GetBytes("GET / HTTP/1.1\r\nHost: " + SocketInfo.Host + "\r\nConnection: close\r\n\r\n");
socket.BeginSend(request, 0, request.Length, 0, ar =>
{
var bytesSent = socket.EndSend(ar);
Console.WriteLine("Sent {0} bytes to server.", bytesSent);
tcs.SetResult(socket);
}, null);
return tcs.Task;
}
public Task<SocketInfo> Receive(Socket socket, SocketInfo socketInfo, TaskCompletionSource<SocketInfo> tcs)
{
socket.BeginReceive(socketInfo.Buffer, 0, SocketInfo.BufferSize, 0, ar =>
{
var bytesRead = socket.EndReceive(ar);
if (bytesRead > 0)
{
socketInfo.Response.Append(Encoding.ASCII.GetString(socketInfo.Buffer, 0, bytesRead));
Receive(socket, socketInfo, tcs);
}
else
{
if (socketInfo.Response.Length > 1)
{
Console.WriteLine("Response: {0}", socketInfo.Response);
}
tcs.SetResult(socketInfo);
}
}, null);
return tcs.Task;
}
public Task<SocketInfo> Receive(Socket socket)
{
var tcs = new TaskCompletionSource<SocketInfo>();
Receive(socket, new SocketInfo(socket), tcs);
return tcs.Task;
}
}
}
@@ -0,0 +1,110 @@
using System;
using MPI;
//mpiexec -n 4 ProjectDistributed.exe
class GraphColoringProblem
{
const int V = 4;
static bool IsSafe(int v, bool[,] graph, int[] color, int c)
{
for (int i = 0; i < V; i++)
{
if (graph[v, i] && c == color[i])
return false;
}
return true;
}
static bool GraphColoringUtil(bool[,] graph, int m, int[] color, int v)
{
if (v == V)
return true;
for (int c = 1; c <= m; c++)
{
if (IsSafe(v, graph, color, c))
{
color[v] = c;
if (GraphColoringUtil(graph, m, color, v + 1))
return true;
color[v] = 0;
}
}
return false;
}
static bool SolveGraphColoring(bool[,] graph, int m, int rank, int size, out int[] colors)
{
int[] color = new int[V];
Array.Fill(color, 0);
bool foundSolution = false;
for (int c = rank + 1; c <= m; c += size)
{
color[0] = c; // Assign a color to the first vertex based on process rank
if (GraphColoringUtil(graph, m, color, 1))
{
foundSolution = true;
break;
}
}
colors = color;
return foundSolution;
}
static void PrintSolution(int[] color)
{
Console.WriteLine("Solution Exists: Following are the assigned colors");
for (int i = 0; i < V; i++)
Console.Write($" {color[i]} ");
Console.WriteLine();
}
static void Main(string[] args)
{
using (new MPI.Environment(ref args))
{
Intracommunicator comm = Communicator.world;
int rank = comm.Rank;
int size = comm.Size;
bool[,] graph = {
{ false, true, true, true },
{ true, false, true, false },
{ true, true, false, true },
{ true, false, true, false }
};
int m = 3; // Number of colors
bool localSolution = SolveGraphColoring(graph, m, rank, size, out int[] colors);
(bool foundSolution, int[] solution) = comm.Allreduce(
(localSolution, colors),
(sol1, sol2) => sol1.Item1 ? sol1 : sol2
);
//bool globalSolution = comm.Reduce(localSolution, Operation<bool>.LogicalOr, 0);
if (rank == 0)
{
if (!foundSolution)
{
Console.WriteLine("No solution exists.");
}
else
{
Console.WriteLine("A solution has been found by one of the processes.");
PrintSolution(solution);
}
}
}
}
}
@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<EnableUnsafeBinaryFormatterSerialization>true</EnableUnsafeBinaryFormatterSerialization>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MPI.NET" Version="1.4.0" />
</ItemGroup>
</Project>
@@ -0,0 +1,96 @@
using System;
using System.Threading.Tasks;
class GraphColoringProblem
{
// Number of vertices in the graph
const int V = 4;
// A utility function to check if the current color assignment is safe for vertex v
static bool IsSafe(int v, bool[,] graph, int[] color, int c)
{
for (int i = 0; i < V; i++)
{
if (graph[v, i] && c == color[i])
return false;
}
return true;
}
// A parallel utility function to solve m coloring problem
static bool GraphColoringUtilParallel(bool[,] graph, int m, int[] color, int v)
{
if (v == V)
return true;
bool result = false;
Parallel.For(1, m + 1, (c, state) =>
{
if (IsSafe(v, graph, color, c))
{
color[v] = c;
if (GraphColoringUtilParallel(graph, m, color, v + 1))
{
result = true;
state.Break(); // Exit parallel loop as a solution is found
}
if (result == false)
color[v] = 0; // Backtrack
}
});
return result;
}
// This function solves the m Coloring problem using parallelism
static bool SolveGraphColoring(bool[,] graph, int m)
{
int[] color = new int[V];
for (int i = 0; i < V; i++)
color[i] = 0;
if (!GraphColoringUtilParallel(graph, m, color, 0))
{
Console.WriteLine("Solution does not exist");
return false;
}
PrintSolution(color);
return true;
}
// A utility function to print solution
static void PrintSolution(int[] color)
{
Console.WriteLine("Solution Exists: Following are the assigned colors");
for (int i = 0; i < V; i++)
Console.Write(" " + color[i] + " ");
Console.WriteLine();
}
// Driver code
static void Main(string[] args)
{
/* Create following graph and test whether it is 3 colorable
(3)---(2)
| / |
| / |
| / |
(0)---(1)
*/
bool[,] graph = {
{ false, true, true, true },
{ true, false, true, false },
{ true, true, false, true },
{ true, false, true, false }
};
// Number of colors
int m = 3;
// Function call
SolveGraphColoring(graph, m);
}
}
@@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>