예제 #1
0
        private void PrintASL(AdjVertexSortedList list, string name, Point point, int size)
        {
            float nameSize = graphics.MeasureString(name, smallFont).Width;

            graphics.DrawString(name, smallFont, textBrush, point);
            point = new Point(point.X + (int)nameSize + 1, point.Y);
            foreach (Edge <VisVertex> edge in list)
            {
                PrintEdgeRectangle(edge, point, size);
                point = new Point(point.X + size, point.Y);
            }
        }
예제 #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);
        }
예제 #3
0
        private void ShowAdjLists()
        {
            string[][] lists     = AdjVertexSortedList.GetStringAdjLists(graph);
            int        maxLenght = GetMaxLenght();

            dgvAdjMatrix.Columns.Clear();
            dgvAdjMatrix.Rows.Clear();
            dgvAdjMatrix.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
            if (maxLenght == 0)
            {
                return;
            }
            for (int i = 0; i <= maxLenght; i++)
            {
                dgvAdjMatrix.Columns.Add(i.ToString(), "");
                dgvAdjMatrix.Columns[i].Width = 60;
            }
            for (int i = 0; i < lists.Length; i++)
            {
                dgvAdjMatrix.Rows.Add();
                dgvAdjMatrix.Rows[i].Height = 18;
            }
            for (int i = 0; i < lists.Length; i++)
            {
                for (int j = 0; j <= lists[i].Length; j++)
                {
                    if (j == 0)
                    {
                        dgvAdjMatrix.Rows[i].Cells[j].Value           = i.ToString();
                        dgvAdjMatrix.Rows[i].Cells[j].Style.BackColor = printer.VertexColor;
                    }
                    else
                    {
                        dgvAdjMatrix.Rows[i].Cells[j].Value = lists[i][j - 1];
                    }
                }
            }

            int GetMaxLenght()
            {
                int max = 0;

                foreach (var row in lists)
                {
                    if (row.Length > max)
                    {
                        max = row.Length;
                    }
                }
                return(max);
            }
        }
예제 #4
0
        public AdjVertexSortedList Union(AdjVertexSortedList list2Union, bool[] isIncluded)
        {
            var unionList = new AdjVertexSortedList();

            while (!this.IsEmpty && !list2Union.IsEmpty)
            {
                if (isIncluded[this.MaxWeightNode.AdjVertexID])
                {
                    this.ExtractMaxWeightEdge();
                }
                //Удаляем из текущего списка ребра,
                //у которых обе вершины входят в текущую компоненту связности
                else if (isIncluded[list2Union.MaxWeightNode.AdjVertexID])
                {
                    list2Union.ExtractMaxWeightEdge();
                }
                //Удаляем из списка для объединения ребра,
                //у которых обе вершины входят в текущую компоненту связности
                else if (this.MaxWeightNode > list2Union.MaxWeightNode)
                {
                    unionList.Add(this.ExtractMaxWeightEdge());
                }
                else
                {
                    unionList.Add(list2Union.ExtractMaxWeightEdge());
                }
            }
            while (!this.IsEmpty)
            {
                if (isIncluded[this.MaxWeightNode.AdjVertexID])
                {
                    this.ExtractMaxWeightEdge();
                }
                else
                {
                    unionList.Add(this.ExtractMaxWeightEdge());
                }
            }
            while (!list2Union.IsEmpty)
            {
                if (isIncluded[list2Union.MaxWeightNode.AdjVertexID])
                {
                    list2Union.ExtractMaxWeightEdge();
                }
                else
                {
                    unionList.Add(list2Union.ExtractMaxWeightEdge());
                }
            }
            return(unionList);
        }
예제 #5
0
        public void PrintDataStructuresPrim(AdjVertexSortedList[] lists,
                                            AdjVertexSortedList mstList, int inMSTSize = 12, int aslSize = 20)
        {
            int width  = Max(GetMaxLenght() * aslSize + 200, dataStructuresArea.Width);
            int height = Max(lists.Length * aslSize + 100, dataStructuresArea.Height);

            bitmap   = new Bitmap(width, height);
            graphics = Graphics.FromImage(bitmap);
            graphics.Clear(areaBackColor);
            Point point = new Point(3, 3);

            PrintInMSTVertices(point, inMSTSize);
            point.Offset(0, inMSTSize + 3);
            PrintASL(mstList, "МОД", point, aslSize);
            point.Offset(0, aslSize + 3);
            for (int i = 0; i < lists.Length; i++)
            {
                if (lists[i].IsEmpty)
                {
                    continue;
                }
                PrintASL(lists[i], i.ToString(), point, aslSize);
                point.Offset(0, aslSize + 3);
            }
            dataStructuresArea.Image = bitmap;

            int GetMaxLenght()
            {
                int max = 0;

                foreach (var row in lists)
                {
                    if (row.Length > max)
                    {
                        max = row.Length;
                    }
                }
                return(max);
            }

            int Max(int a, int b)
            {
                if (a > b)
                {
                    return(a);
                }
                return(b);
            }
        }
        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));
        }
예제 #7
0
        public static AdjVertexSortedList[] GetAdjLists(Graph <VisVertex> graph)
        {
            var lists = new AdjVertexSortedList[graph.Order]; //Создаем массив списков смежности

            for (int i = 0; i < graph.Order; i++)             //Создаем сп.смеж-и для каждой вершины графа
            {
                lists[i] = new AdjVertexSortedList();
            }
            foreach (Edge <VisVertex> edge in graph.Edges)//Распределяем ребра по спискам
            {
                if (edge.V1Id == edge.V2Id)
                {
                    continue;               //Пропускаем петли
                }
                lists[edge.V1Id].Add(edge); //Добавляем ребро в список первой вершины
                lists[edge.V2Id].Add(edge.Reverse());
                //Добавляем ребро в список второй вершины
                //(переворачиваем ребро, т.к. для второй вешины смежняая будет первая)
            }
            return(lists);
        }
        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();
        }
예제 #9
0
 public void Dispose()
 {
     list        = null;
     currentNode = null;
 }
예제 #10
0
 public AdjListEnumerator(AdjVertexSortedList list)
 {
     this.list   = list;
     currentNode = list.Head;
     position    = -1;
 }