From dd47678e74752e08a94c59ec479502bdc75bc310 Mon Sep 17 00:00:00 2001 From: SergeyKuz1001 Date: Wed, 11 Dec 2019 16:28:54 +0300 Subject: [PATCH] Cleaning master --- Task02/GeneralResources.cs | 64 ------------------- Task02/ParallelAlgoFloyd.cs | 54 ---------------- Task02/ParallelAlgoKruskal.cs | 86 ------------------------- Task02/ParallelAlgoPrim.cs | 91 -------------------------- Task02/Program.cs | 110 -------------------------------- Task02/SequentialAlgoFloyd.cs | 27 -------- Task02/SequentialAlgoKruskal.cs | 46 ------------- 7 files changed, 478 deletions(-) delete mode 100644 Task02/GeneralResources.cs delete mode 100644 Task02/ParallelAlgoFloyd.cs delete mode 100644 Task02/ParallelAlgoKruskal.cs delete mode 100644 Task02/ParallelAlgoPrim.cs delete mode 100644 Task02/Program.cs delete mode 100644 Task02/SequentialAlgoFloyd.cs delete mode 100644 Task02/SequentialAlgoKruskal.cs diff --git a/Task02/GeneralResources.cs b/Task02/GeneralResources.cs deleted file mode 100644 index d6b9492..0000000 --- a/Task02/GeneralResources.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System; -using System.IO; - -namespace Task02 -{ - public class Graph - { - public const int INF = 1000000000; - public int[,] graphMatrix; - public (int, int, int)[] graphListEdges; - public int graphAmountVertexes; - static int NumberOfConventionalUnitsInTotal = 1000000; - - public Graph(int amountVertexes, int approximateAmountEdges, int minWeight, int maxWeight) - { - graphAmountVertexes = amountVertexes; - graphMatrix = new int[amountVertexes, amountVertexes]; - Random random = new Random(); - int partAmountEdgesFromMax = (int)((long)approximateAmountEdges * NumberOfConventionalUnitsInTotal / - (amountVertexes * (amountVertexes - 1) / 2)); - int exectAmountEdges = 0; - for (int i = 0; i < amountVertexes; i++) - { - for (int j = i + 1; j < amountVertexes; j++) - { - if (random.Next(NumberOfConventionalUnitsInTotal) < partAmountEdgesFromMax) - { - int weight = random.Next(minWeight, maxWeight); - graphMatrix[i, j] = graphMatrix[j, i] = weight; - exectAmountEdges++; - } - else - { - graphMatrix[i, j] = graphMatrix[j, i] = INF; - } - } - } - - graphListEdges = new (int, int, int)[exectAmountEdges]; - int k = 0; - for (int i = 0; i < amountVertexes; i++) - { - for (int j = i + 1; j < amountVertexes; j++) - { - if (graphMatrix[i, j] != INF) - { - graphListEdges[k] = (graphMatrix[i, j], i, j); - k++; - } - } - } - - StreamWriter foutMatrix = new StreamWriter("matrix.txt"); - foutMatrix.Write($"{amountVertexes} {exectAmountEdges}\n"); - for (k = 0; k < exectAmountEdges; k++) - { - foutMatrix.Write($"{graphListEdges[k].Item2 + 1} " + - $"{graphListEdges[k].Item3 + 1} " + - $"{graphListEdges[k].Item1}\n"); - } - foutMatrix.Close(); - } - } -} diff --git a/Task02/ParallelAlgoFloyd.cs b/Task02/ParallelAlgoFloyd.cs deleted file mode 100644 index c7c74a4..0000000 --- a/Task02/ParallelAlgoFloyd.cs +++ /dev/null @@ -1,54 +0,0 @@ -using System; -using System.Threading.Tasks; - -namespace Task02 -{ - public class ParallelAlgoFloyd - { - private static int[,] dist; - - static void parallelProc(int n, int k, int i) - { - for (int j = 0; j < n; j++) - { - if (j != k) - { - if (dist[i, j] > dist[i, k] + dist[k, j]) - dist[i, j] = dist[i, k] + dist[k, j]; - } - } - } - - public static int[,] Execute(Graph graph) - { - int n = graph.graphAmountVertexes; - dist = new int[n, n]; - Task[] tasks = new Task[n - 1]; - Array.Copy(graph.graphMatrix, dist, n * n); - - for (int k = 0; k < n; k++) - { - for (int i = 0; i < n; i++) - { - if (i != k) - { - int newK = k; - int newI = i; - // передаём newK и newI для того, чтобы избежать замыкания - tasks[i < k ? i : i - 1] = Task.Run(() => parallelProc(n, newK, newI)); - // так как i из 0..(n-1), но одно из значений i не используется (блокируется - // условием i != k), то для единообразия обработки Task tasks.Length == n - 1, - // и выражение (i < k ? i : i - 1) задаёт биекцию из [0; k-1] U [k+1; n-1] в - // [0; n-2] - } - } - // ждём выполнения всех задач для того, чтобы случайно не получилось так, что - // задача с большим k не обогнала задачу с меньшим k (и чтобы нам всегда хватило - // ровно n - 1 задачи) - Task.WaitAll(tasks); - } - - return dist; - } - } -} diff --git a/Task02/ParallelAlgoKruskal.cs b/Task02/ParallelAlgoKruskal.cs deleted file mode 100644 index 4feee45..0000000 --- a/Task02/ParallelAlgoKruskal.cs +++ /dev/null @@ -1,86 +0,0 @@ -using System; -using System.Threading; - -namespace Task02 -{ - public class ParallelAlgoKruskal - { - static Random rand = new Random(); - static int[] dsu; - static int parallelDepth = 3; // глубина рекурсии, до которой происходит распараллеливание сортировки рёбер - - static int getDsu(int x) - { - return dsu[x] == -1 ? x : dsu[x] = getDsu(dsu[x]); - } - - static bool unionDsu(int x, int y) - { - x = getDsu(x); - y = getDsu(y); - if (x == y) - return false; - if (rand.Next(0, 1) == 1) // псевдорандом - dsu[y] = x; - else - dsu[x] = y; - return true; - } - - static void parallelSort(T[] edges, T[] buffer, int LIndex, int RIndex, int parallelDepth) where T : IComparable - { - // parallelSort до глубины parallelDepth реализуется как параллельная MergeSort, а глубже - встроенную сортировку - if (parallelDepth <= 0) - { - Array.Sort(edges, LIndex, RIndex - LIndex); - return; - } - if (RIndex - LIndex <= 1) - return; - int MIndex = (LIndex + RIndex) / 2; - - // чтобы поток просто так не стоял, он берёт на себя сортировку половины массива, а другую отдаёт новому потоку - Thread helperThread = new Thread(() => parallelSort(edges, buffer, LIndex, MIndex, parallelDepth - 1)); - helperThread.Start(); - parallelSort(edges, buffer, MIndex, RIndex, parallelDepth - 1); - helperThread.Join(); - - // объединение двух отсортированных массивов через buffer - int i = LIndex, j = MIndex; - for (int k = LIndex; k < RIndex; k++) - { - if (i == MIndex || (j != RIndex && edges[i].CompareTo(edges[j]) >= 0)) - { - buffer[k] = edges[j]; - j++; - } - else - { - buffer[k] = edges[i]; - i++; - } - } - for (int k = LIndex; k < RIndex; k++) - edges[k] = buffer[k]; - } - - public static int Execute(Graph graph) - { - int ans = 0; - (int, int, int)[] edges = graph.graphListEdges; - parallelSort(edges, new (int, int, int)[edges.Length], 0, edges.Length, parallelDepth); - - dsu = new int[graph.graphAmountVertexes]; - Array.Fill(dsu, -1); - - for (int i = 0; i < edges.Length; i++) - { - if (unionDsu(edges[i].Item2, edges[i].Item3)) - { - ans += edges[i].Item1; - } - } - return ans; - } - } -} diff --git a/Task02/ParallelAlgoPrim.cs b/Task02/ParallelAlgoPrim.cs deleted file mode 100644 index 9734ae9..0000000 --- a/Task02/ParallelAlgoPrim.cs +++ /dev/null @@ -1,91 +0,0 @@ -using System; -using System.Threading; -using System.Collections.Generic; - -namespace Task02 -{ - public class ParallelAlgoPrim - { - static int minDistVertex; // вершина, не лежащая в дереве, расстояние до которой от дерева минимально - static int newMinDistVertex; - static int amountThreads = 6; - static int runningThreads; // количество выполняющихся потоков - static int chunkSize; - static Mutex mutRunningThreads = new Mutex(); // блокировка при изменении runningThreads - static Mutex mutNewV = new Mutex(); // блокировка при чтении и изменении newV - static HashSet tree; // вершины, лежащие в остовном дереве - static int[] minDistToTree; - - static void FindNewV(Graph graph, int LIndex, int RIndex) - { - // нахождение очередной вершины с минимальным расстоянием до дерева - int localMinDistVertex = -1; // локальный ответ - - for (int to = LIndex; to < RIndex; to++) - { - if (!tree.Contains(to)) - { - // обновление минимального расстояния после добавления v в дерево - if (minDistToTree[to] > graph.graphMatrix[minDistVertex, to]) - { - minDistToTree[to] = graph.graphMatrix[minDistVertex, to]; - } - - // обновление локального ответа - if (localMinDistVertex == -1 || minDistToTree[localMinDistVertex] > minDistToTree[to]) - localMinDistVertex = to; - } - } - - if (localMinDistVertex != -1) - { - mutNewV.WaitOne(); - // обновление глобального ответа - if (newMinDistVertex == -1 || minDistToTree[newMinDistVertex] > minDistToTree[localMinDistVertex]) - newMinDistVertex = localMinDistVertex; - mutNewV.ReleaseMutex(); - } - - mutRunningThreads.WaitOne(); - runningThreads--; - mutRunningThreads.ReleaseMutex(); - } - - public static int Execute(Graph graph) - { - int ans = 0; - tree = new HashSet(); - minDistToTree = new int[graph.graphAmountVertexes]; - Array.Fill(minDistToTree, Graph.INF); - chunkSize = graph.graphAmountVertexes / amountThreads; - - // начинаем с вершины 0 - minDistToTree[0] = 0; - minDistVertex = 0; - - while (minDistVertex != -1) - { - ans += minDistToTree[minDistVertex]; - tree.Add(minDistVertex); - - newMinDistVertex = -1; - - runningThreads = amountThreads; - for (int i = 0; i < amountThreads - 1; i++) - { - int LIndex = chunkSize * i; - int RIndex = chunkSize * (i + 1); - ThreadPool.QueueUserWorkItem(_ => FindNewV(graph, LIndex, RIndex)); - } - // загрзим главный поток чтобы он просто так не ждал - FindNewV(graph, chunkSize * (amountThreads - 1), graph.graphAmountVertexes); - - while (runningThreads > 0) {} - - minDistVertex = newMinDistVertex; - } - - return ans; - } - } -} diff --git a/Task02/Program.cs b/Task02/Program.cs deleted file mode 100644 index ad6bf93..0000000 --- a/Task02/Program.cs +++ /dev/null @@ -1,110 +0,0 @@ -using System; -using System.IO; -using System.Diagnostics; - -namespace Task02 -{ - class Program - { - static void Main() - { - StreamWriter foutFloyd = new StreamWriter("floyd.txt"); - StreamWriter foutKruskal = new StreamWriter("kruskal.txt"); - StreamWriter foutPrim = new StreamWriter("prim.txt"); - - Console.WriteLine("Введите количество вершин нового графа:"); - string inputN = Console.ReadLine(); - int n = int.Parse(inputN); - Console.WriteLine("Введите примерное количество рёбер нового графа:"); - string inputM = Console.ReadLine(); - int m = int.Parse(inputM); - Console.WriteLine("Введите два числа - диапазон весов рёбер нового графа:"); - string[] inputW = Console.ReadLine().Split(" "); - int minWeight = int.Parse(inputW[0]); - int maxWeight = int.Parse(inputW[1]); - - Console.WriteLine("\nСоздание нового графа..."); - Graph graph = new Graph(n, m, minWeight, maxWeight); - Console.WriteLine("Новый граф успешно создан.\n"); - - Stopwatch timeSequentialFloyd = Stopwatch.StartNew(); - int[,] ansSequentialFloyd = SequentialAlgoFloyd.Execute(graph); - timeSequentialFloyd.Stop(); - Console.WriteLine($"Время исполнения последовательного алгоритма Флойда = {timeSequentialFloyd.ElapsedMilliseconds} мс."); - - Stopwatch timeParallelFloyd = Stopwatch.StartNew(); - int[,] ansParallelFloyd = ParallelAlgoFloyd.Execute(graph); - timeParallelFloyd.Stop(); - Console.WriteLine($"Время исполнения параллельного алгоритма Флойда = {timeParallelFloyd.ElapsedMilliseconds} мс."); - - Stopwatch timeSequentialKruskal = Stopwatch.StartNew(); - int ansSequentialKruskal = SequentialAlgoKruskal.Execute(graph); - timeSequentialKruskal.Stop(); - Console.WriteLine($"Время исполнения последовательного алгоритма Краскала = {timeSequentialKruskal.ElapsedMilliseconds} мс."); - - Stopwatch timeParallelKruskal = Stopwatch.StartNew(); - int ansParallelKruskal = ParallelAlgoKruskal.Execute(graph); - timeParallelKruskal.Stop(); - Console.WriteLine($"Время исполнения параллельного алгоритма Краскала = {timeParallelKruskal.ElapsedMilliseconds} мс."); - - Stopwatch timeParallelPrim = Stopwatch.StartNew(); - int ansParallelPrim = ParallelAlgoPrim.Execute(graph); - timeParallelPrim.Stop(); - Console.WriteLine($"Время исполнения параллельного алгоритма Прима = {timeParallelPrim.ElapsedMilliseconds} мс."); - - Console.WriteLine(); - - bool ansEquals = true; - for (int i = 0; i < n; i++) - { - for (int j = 0; j < n; j++) - { - if (ansSequentialFloyd[i, j] != ansParallelFloyd[i, j]) - { - ansEquals = false; - break; - } - } - } - if (ansEquals) - { - Console.WriteLine("OK: Ответ параллельного алгоритма Флойда совпал с последовательным."); - } - else - { - Console.WriteLine("WA: Ответ параллельного алгоритма Флойда не совпал с последовательным."); - } - - if (ansSequentialKruskal == ansParallelKruskal) - { - Console.WriteLine("OK: Ответ параллельного алгоритма Краскала совпал с последовательным."); - } - else - { - Console.WriteLine("WA: Ответ параллельного алгоритма Краскала не совпал с последовательным."); - } - - if (ansSequentialKruskal == ansParallelPrim) - { - Console.WriteLine("OK: Ответ параллельного алгоритма Прима совпал с последовательным алгоритмом Краскала."); - } - else - { - Console.WriteLine("WA: Ответ параллельного алгоритма Прима не совпал с последовательным алгоритмом Краскала."); - } - - for (int i = 0; i < n; i++) - { - for (int j = 0; j < n; j++) - { - foutFloyd.Write($"{ansParallelFloyd[i, j]}{(j + 1 == n ? '\n' : ' ')}"); - } - } - foutKruskal.Write(ansParallelKruskal); - foutPrim.Write(ansParallelPrim); - foutFloyd.Close(); - foutKruskal.Close(); - foutPrim.Close(); - } - } -} diff --git a/Task02/SequentialAlgoFloyd.cs b/Task02/SequentialAlgoFloyd.cs deleted file mode 100644 index 2586ae1..0000000 --- a/Task02/SequentialAlgoFloyd.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; - -namespace Task02 -{ - public class SequentialAlgoFloyd - { - public static int[,] Execute(Graph graph) - { - int n = graph.graphAmountVertexes; - int[,] dist = new int[n, n]; - Array.Copy(graph.graphMatrix, dist, n * n); - - for (int k = 0; k < n; k++) - { - for (int i = 0; i < n; i++) - { - for (int j = 0; j < n; j++) - { - if (dist[i, j] > dist[i, k] + dist[k, j]) - dist[i, j] = dist[i, k] + dist[k, j]; - } - } - } - return dist; - } - } -} diff --git a/Task02/SequentialAlgoKruskal.cs b/Task02/SequentialAlgoKruskal.cs deleted file mode 100644 index a371dbc..0000000 --- a/Task02/SequentialAlgoKruskal.cs +++ /dev/null @@ -1,46 +0,0 @@ -using System; - -namespace Task02 -{ - public class SequentialAlgoKruskal - { - static int[] dsu; - - static int getDsu(int x) - { - return dsu[x] == -1 ? x : dsu[x] = getDsu(dsu[x]); - } - - static bool unionDsu(int x, int y) - { - x = getDsu(x); - y = getDsu(y); - if (x == y) - return false; - if ((x + 2 * y) % 4 * 2 % 6 != 0) // псевдорандом - dsu[y] = x; - else - dsu[x] = y; - return true; - } - - public static int Execute(Graph graph) - { - int ans = 0; - (int, int, int)[] edges = graph.graphListEdges; - Array.Sort(edges); - - dsu = new int[graph.graphAmountVertexes]; - Array.Fill(dsu, -1); - - for (int i = 0; i < edges.Length; i++) - { - if (unionDsu(edges[i].Item2, edges[i].Item3)) - { - ans += edges[i].Item1; - } - } - return ans; - } - } -}