public static Graph <VisVertex> GetMstPrim(Graph <VisVertex> graph) { if (!graph.IsConnected) { throw new Exception("Граф не связен"); } Random rnd = new Random(); bool[] inMST = new bool[graph.Order]; //Создаем логический массив для проверки вхождения вершин в МОД List <Vertex <VisVertex> > verticesMST = graph.VerticesClone; //Создаем список вершин МОД List <Edge <VisVertex> > edgesMST = new List <Edge <VisVertex> >(); //Создаем список ребер МОД var adjVertexSortLists = GetAdjLists(graph); //Создаем сортированные списки смежности для вершин графа var adjVertexSortListMST = new AdjVertexSortedList(); //Создаем пустой сортированный список смежности для всего МОД int firsrVertex = rnd.Next(0, graph.Order); //Выбираем случайную вершину для начала построения МОД inMST[firsrVertex] = true; //Отмечаем произвольную вершину, как включенную в МОД adjVertexSortListMST = adjVertexSortListMST.Union( adjVertexSortLists[firsrVertex], inMST); //Объединяем список смежности МОД и список смежности выбраной вершины //(при объединении сортировка поддерживается) for (int i = 0; i < graph.Order - 1; i++) //Цикл для построения МОД, шагов по количеству вершин - 1 { Edge <VisVertex> edge2Add = adjVertexSortListMST.ExtractMinWeightEdge(); //выбираем из списка смежности МОД ребро минимального веса AddEdge(edge2Add, verticesMST, edgesMST); //Добавляем ребро мнимального веса в МОД inMST[edge2Add.V2Id] = true; //Отмечаем присоединенную вершину, как включенную в МОД adjVertexSortListMST = adjVertexSortListMST.Union( adjVertexSortLists[edge2Add.V2Id], inMST); //Объединяем списки смежности МОД и последней добавленной вершины //(при этом ребра внутри МОД удаляются) } if (edgesMST.Count != graph.Order - 1) { throw new Exception("Ошибка МОД не найдено"); } return(new Graph <VisVertex>(verticesMST, edgesMST)); }
public async void PrimsAlgorithmVisAsync(Color mstColor, bool startFrom0) { if (!graph.IsConnected) { visualisator.Print("Остовное дерево не может быть построено. Граф не связен!"); visualisator.ApEndLog("Остовное дерево не может быть построено. Граф не связен!"); return; } form.BlockTabControl(); int mstWeight = 0; bool[] inMST = new bool[graph.Order]; //Создаем логический массив для проверки вхождения вершин в МОД List <Edge <VisVertex> > edgesMST = new List <Edge <VisVertex> >(); //Создаем список ребер МОД var adjVertexSortLists = GetAdjLists(graph); //Создаем сортированные списки смежности для вершин графа var adjVertexSortListMST = new AdjVertexSortedList(); //Создаем пустой сортированный список смежности для всего МОД int firsrVertex = startFrom0 ? 0 : rnd.Next(0, graph.Order); //Выбираем случайную вершину для начала построения МОД inMST[firsrVertex] = true; //Отмечаем произвольную вершину, как включенную в МОД visualisator.SetVertexColor(firsrVertex, mstColor); visualisator.Print(startFrom0 ? "Начиная с нулевой вершины" : "Начальная вершина выбрана произвольно"); visualisator.ApEndLog(startFrom0 ? "Начиная с нулевой вершины" : "Произвольный выбор начальной вершины МОД."); await Task.Delay(SleepInterval); adjVertexSortListMST = adjVertexSortListMST.Union( adjVertexSortLists[firsrVertex], inMST); //Объединяем список смежности МОД и список смежности выбраной вершины //(при объединении сортировка поддерживается) for (int i = 0; i < graph.Order - 1; i++) //Цикл для построения МОД, шагов по количеству вершин - 1 { Edge <VisVertex> edge2Add = adjVertexSortListMST.ExtractMinWeightEdge(); //выбираем из списка смежности МОД ребро минимального веса edgesMST.Add(edge2Add); //Добавляем ребро мнимального веса в МОД inMST[edge2Add.V2Id] = true; //Отмечаем присоединенную вершину, как включенную в МОД mstWeight += edge2Add.Weight; adjVertexSortListMST = adjVertexSortListMST.Union( adjVertexSortLists[edge2Add.V2Id], inMST); //Объединяем списки смежности МОД и последней добавленной вершины //(при этом ребра внутри МОД удаляются) visualisator.ApEndLog($"Шаг {i + 1}. Выбираем ребро минимального веса, " + $"соединяющее вершину внутри и вне МОД - {edge2Add}"); visualisator.SetEdgeColor(edge2Add, mstColor); visualisator.SetVertexColor(edge2Add.V2Id, mstColor); visualisator.Print($"Добавление к МОД смежного ребра минимального веса. " + $"Всего ребер {edgesMST.Count}. Общий вес {mstWeight}."); visualisator.PrintDataStructuresPrim(adjVertexSortLists, adjVertexSortListMST); await Task.Delay(SleepInterval); } if (edgesMST.Count != graph.Order - 1) { throw new Exception("Ошибка МОД не найдено"); } else { visualisator.Print( $"Минимальное остовное дерево построено. Общий вес {mstWeight}."); visualisator.ApEndLog( $"Минимальное остовное дерево построено. Общий вес {mstWeight}."); visualisator.PrintDataStructuresPrim(adjVertexSortLists, adjVertexSortListMST); } form.UnBlockTabControl(); }