public static Graph <VisVertex> GetMST_KrusculDSU(Graph <VisVertex> graph) { Edge <VisVertex>[] sortedEdges = GetSortedEdges(graph.EdgesClone); Graph <VisVertex> mst = new Graph <VisVertex>(graph.VerticesClone);//Создаем МОД DisjointSet dsu = new DisjointSet(graph.Order); foreach (Edge <VisVertex> edge in sortedEdges) { if (mst.EdgesCount == graph.Order - 1) { break; //Если МОД построен выходим из цикла } if (dsu.InTheSameSet(edge.V1Id, edge.V2Id)) { continue; } //Если вершины ребра в одной компоненте пропускаем ребро mst.AddEdge(edge); //Добавляем ребро мнимального веса в МОД dsu.UnionSets(edge.V1Id, edge.V2Id); //Объединяем связанные компоненты } if (mst.EdgesCount != graph.Order - 1) { throw new Exception("Ошибка МОД не найдено"); } return(mst); }
public async void KrusculAlgorithmVisAsync() { if (!graph.IsConnected) { visualisator.Print("Остовное дерево не может быть построено. Граф не связен!"); visualisator.ApEndLog("Остовное дерево не может быть построено. Граф не связен!"); return; } form.BlockTabControl(); int order = graph.Order; Edge <VisVertex>[] sortedEdges = GetSortedEdges(graph.EdgesClone); Graph <VisVertex> mst = new Graph <VisVertex>(graph.VerticesClone);//Создаем МОД DisjointSet dsu = new DisjointSet(order); SetVerticesDifferentColors(); visualisator.Print("Маркировка вершин"); visualisator.ApEndLog("МОД сотоит из отдельных вершин - компонент связности, " + "маркированных различными цветами" + "\nПоследовательно простомтрим ребра, отсортированные по неубыванию веса."); visualisator.PrintDataStructuresKruskal(sortedEdges, sortedEdges[0], dsu, colors); await Task.Delay(SleepInterval); foreach (Edge <VisVertex> edge in sortedEdges) { if (mst.EdgesCount == order - 1) { break; //Если МОД построен выходим из цикла } if (dsu.InTheSameSet(edge.V1Id, edge.V2Id)) { visualisator.ApEndLog( $"Ребро {edge} соединяет вершины из одной компоненты - пропускаем."); visualisator.PrintDataStructuresKruskal(sortedEdges, edge, dsu, colors); await Task.Delay(SleepInterval); continue; //Если вершины ребра в одной компоненте пропускаем ребро } mst.AddEdge(edge); //Добавляем ребро мнимального веса в МОД dsu.UnionSets(edge.V1Id, edge.V2Id); //Объединяем связанные компоненты RefreshColors(dsu, mst); visualisator.Print($"Добавление ребра минимального веса. " + $"Всего ребер {mst.EdgesCount}. Общий вес {mst.TotalWeight}."); visualisator.ApEndLog( $"Ребро {edge} соединяет вершины из разных компонент - добавляем в МОД. " + $"Объединяем связанные ребром компоненты."); visualisator.PrintDataStructuresKruskal(sortedEdges, edge, dsu, colors); await Task.Delay(SleepInterval); } if (mst.EdgesCount != order - 1) { throw new Exception("Ошибка МОД не найдено"); } else { visualisator.Print( $"Минимальное остовное дерево построено. Общий вес {mst.TotalWeight}."); visualisator.ApEndLog( $"Минимальное остовное дерево построено. Общий вес {mst.TotalWeight}."); } form.UnBlockTabControl(); }