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);
        }
예제 #2
0
        public AdjVertexSortedList Union(AdjVertexSortedList list2Union, DisjointSet dsu)
        {
            var unionList = new AdjVertexSortedList();

            while (!this.IsEmpty && !list2Union.IsEmpty)
            {
                if (dsu.InTheSameSet(this.MaxWeightEdge.V1Id, this.MaxWeightEdge.V2Id))
                {
                    this.ExtractMaxWeightEdge();
                }
                //Удаляем из текущего списка ребра,
                //у которых обе вершины входят в одну компоненту связности
                else if (dsu.InTheSameSet(
                             list2Union.MaxWeightEdge.V1Id, list2Union.MaxWeightEdge.V2Id))
                {
                    list2Union.ExtractMaxWeightEdge();
                    //Удаляем из списка для объединения ребра,
                    //у которых обе вершины входят в одну компоненту связности
                }
                else if (this.MaxWeightNode > list2Union.MaxWeightNode)
                {
                    unionList.Add(this.ExtractMaxWeightEdge());
                }
                else
                {
                    unionList.Add(list2Union.ExtractMaxWeightEdge());
                }
            }
            while (!this.IsEmpty)
            {
                if (dsu.InTheSameSet(this.MaxWeightEdge.V1Id, this.MaxWeightEdge.V2Id))
                {
                    this.ExtractMaxWeightEdge();
                }
                else
                {
                    unionList.Add(this.ExtractMaxWeightEdge());
                }
            }
            while (!list2Union.IsEmpty)
            {
                if (dsu.InTheSameSet(list2Union.MaxWeightEdge.V1Id, list2Union.MaxWeightEdge.V2Id))
                {
                    list2Union.ExtractMaxWeightEdge();
                }
                else
                {
                    unionList.Add(list2Union.ExtractMaxWeightEdge());
                }
            }
            return(unionList);
        }
        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();
        }