From 6f54d71639b043b9ca813b8f70811f5a0180f106 Mon Sep 17 00:00:00 2001 From: Kuzivanov Sergey <43182277+SergeyKuz1001@users.noreply.github.com> Date: Fri, 1 Nov 2019 17:04:09 +0300 Subject: [PATCH] Create ParallelAlgoPrim.cs --- Task02/ParallelAlgoPrim.cs | 91 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 Task02/ParallelAlgoPrim.cs diff --git a/Task02/ParallelAlgoPrim.cs b/Task02/ParallelAlgoPrim.cs new file mode 100644 index 0000000..77f6344 --- /dev/null +++ b/Task02/ParallelAlgoPrim.cs @@ -0,0 +1,91 @@ +using System; +using System.Threading; +using System.Collections.Generic; + +namespace Task02 +{ + public class ParallelAlgoPrim + { + static int v; // вершина, не лежащая в дереве, расстояние до которой от дерева минимально + static int newV; + 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(int LIndex, int RIndex) + { + // нахождение очередной вершины с минимальным расстоянием до дерева + int localV = -1; // локальный ответ + + for (int to = LIndex; to < RIndex; to++) + { + if (!tree.Contains(to)) + { + // обновление минимального расстояния после добавления v в дерево + if (minDistToTree[to] > GeneralResources.graphMatrix[v, to]) + { + minDistToTree[to] = GeneralResources.graphMatrix[v, to]; + } + + // обновление локального ответа + if (localV == -1 || minDistToTree[localV] > minDistToTree[to]) + localV = to; + } + } + + if (localV != -1) + { + mutNewV.WaitOne(); + // обновление глобального ответа + if (newV == -1 || minDistToTree[newV] > minDistToTree[localV]) + newV = localV; + mutNewV.ReleaseMutex(); + } + + mutRunningThreads.WaitOne(); + runningThreads--; + mutRunningThreads.ReleaseMutex(); + } + + public static int Execute() + { + int ans = 0; + tree = new HashSet(); + minDistToTree = new int[GeneralResources.n]; + Array.Fill(minDistToTree, GeneralResources.INF); + chunkSize = GeneralResources.n / amountThreads; + + // начинаем с вершины 0 + minDistToTree[0] = 0; + v = 0; + + while (v != -1) + { + ans += minDistToTree[v]; + tree.Add(v); + + newV = -1; + + runningThreads = amountThreads; + for (int i = 0; i < amountThreads - 1; i++) + { + int LIndex = chunkSize * i; + int RIndex = chunkSize * (i + 1); + ThreadPool.QueueUserWorkItem(_ => FindNewV(LIndex, RIndex)); + } + // загрзим главный поток чтобы он просто так не ждал + FindNewV(chunkSize * (amountThreads - 1), GeneralResources.n); + + while (runningThreads > 0) {} + + v = newV; + } + + return ans; + } + } +}