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