Пример #1
0
        public void Prim(CGraph graph, Grid grid)
        {
            List <Vertex> lv      = graph.Vertices;
            List <Edge>   le      = graph.Edges;
            List <Vertex> tree    = new List <Vertex>(); //Список, представляющий собой остовное дерево
            List <Edge>   tredges = new List <Edge>();   //Список с ребрами остовного дерева
            Vertex        vf      = lv.First();          //Первая вершина (Шаг 1)

            tree.Add(vf);

            while (tree.Count != lv.Count)                //Пока все вершины не вошли в дерево, повторяем действия (Шаг 2)
            {
                List <Edge> incedges = new List <Edge>(); //Список ребер, инцидентных вершинам остовного дерева, идущих к вершинам, не принадлежащим дереву

                int  min  = int.MaxValue;
                Edge emin = null;          //Ребро минимального веса

                foreach (Vertex v in tree) //Наполнения списка incedges
                {
                    foreach (Edge e in le)
                    {
                        if (e.Start == v || e.End == v && ((tree.Contains(e.Start) && !tree.Contains(e.End)) || (tree.Contains(e.End) && !tree.Contains(e.Start))))
                        {
                            incedges.Add(e);
                        }
                    }
                }

                foreach (Edge e in incedges) //Нахождение минимального ребра в списке
                {
                    if (e.Weight < min && ((tree.Contains(e.Start) && !tree.Contains(e.End)) || (tree.Contains(e.End) && !tree.Contains(e.Start))))
                    {
                        emin = e;
                        min  = e.Weight;
                    }
                }

                tredges.Add(emin);            //Добавление ребра к списку ребер оствоного дерева

                if (!tree.Contains(emin.End)) //Добавление вершины в дерево
                {
                    tree.Add(emin.End);
                }
                else
                {
                    tree.Add(emin.Start);
                }
            }

            foreach (Edge e in le)//Удаление ребер, не принадлежащих остовному дереву
            {
                if (!tredges.Contains(e))
                {
                    grid.Children.Remove(e.TB);
                    grid.Children.Remove(e.Line);
                }
            }
        }
Пример #2
0
        public async Task AnimatedPrim(CGraph graph, Grid grid) //Анимированная версия алгоритма
        {
            List <Vertex> lv      = graph.Vertices;
            List <Edge>   le      = graph.Edges;
            List <Vertex> tree    = new List <Vertex>();
            List <Edge>   tredges = new List <Edge>();
            Vertex        vf      = lv.First();

            tree.Add(vf);

            while (tree.Count != lv.Count)
            {
                List <Edge> incedges = new List <Edge>();

                int  min  = int.MaxValue;
                Edge emin = null;

                foreach (Vertex v in tree)
                {
                    foreach (Edge e in le)
                    {
                        if (e.Start == v || e.End == v && ((tree.Contains(e.Start) && !tree.Contains(e.End)) || (tree.Contains(e.End) && !tree.Contains(e.Start))))
                        {
                            incedges.Add(e);
                        }
                    }
                }

                foreach (Edge e in incedges)
                {
                    e.Line.Stroke = Brushes.Red;
                    if (e.Weight < min && ((tree.Contains(e.Start) && !tree.Contains(e.End)) || (tree.Contains(e.End) && !tree.Contains(e.Start))))
                    {
                        emin = e;
                        min  = e.Weight;
                    }
                    await Task.Delay(400);

                    e.Line.Stroke = Brushes.Black;
                }
                tredges.Add(emin);
                await Blink(emin.Line);

                if (!tree.Contains(emin.End))
                {
                    tree.Add(emin.End);
                }
                else
                {
                    tree.Add(emin.Start);
                }
            }

            foreach (Edge e in le)
            {
                await Task.Delay(200);

                if (!tredges.Contains(e))
                {
                    grid.Children.Remove(e.TB);
                    grid.Children.Remove(e.Line);
                }
            }
        }
Пример #3
0
        public async Task Start(CGraph graph, Grid grid)
        {
            List <Vertex>         lv       = graph.Vertices;
            List <Edge>           le       = graph.Edges;
            List <Edge>           tredges  = new List <Edge>();           //Список с ребрами остовного дерева
            List <List <Vertex> > segments = new List <List <Vertex> >(); //Список сегментов

            foreach (Edge e in le)
            {
                e.Line.Stroke = Brushes.Black;
            }
            foreach (Vertex v in lv)
            {
                v.Ellipse.Stroke = Brushes.Black;
            }

            foreach (Vertex v in lv) //Шаг 1
            {
                List <Vertex> segment = new List <Vertex>();
                segment.Add(v);
                segments.Add(segment);
            }

            while (tredges.Count != lv.Count - 1)         //Шаг 2
            {
                List <Edge> edgelist = new List <Edge>(); //Список выбранных ребер минимальной стоимости

                foreach (List <Vertex> segment in segments)
                {
                    List <Edge> edges = new List <Edge>(); //Список ребер, инцидентных сегменту

                    foreach (Vertex v1 in segment)         //Заполнение списка edges
                    {
                        foreach (Edge e in le)
                        {
                            if ((e.End == v1 && !segment.Contains(e.Start)) || (e.Start == v1 && !segment.Contains(e.End)))
                            {
                                if (!edges.Contains(e))
                                {
                                    edges.Add(e);
                                }
                            }
                        }
                    }

                    List <Line> ls = new List <Line>();//Список линий, представляющих собой ребра в графе
                    foreach (Edge e in edges)
                    {
                        ls.Add(e.Line);
                    }

                    await Blink(ls.ToArray());//Моргание линий

                    int  min  = int.MaxValue;
                    Edge emin = null;
                    foreach (Edge e in edges)//Поиск минимального по стоимости ребра
                    {
                        if (e.Weight < min)
                        {
                            emin = e;
                            min  = e.Weight;
                        }
                    }

                    emin.Line.Stroke = Brushes.Green; //Подсветка ребра в зеленый

                    if (!tredges.Contains(emin))      //Добавление ребра в список ребер остовного дерева
                    {
                        tredges.Add(emin);
                    }

                    if (!edgelist.Contains(emin))//Добавление ребра в список минимальных ребер
                    {
                        edgelist.Add(emin);
                    }
                }

                foreach (Edge e in edgelist)//Объединение сегментов по выбранным ребрам минимальной стоимости
                {
                    List <Vertex> segment1 = null;
                    List <Vertex> segment2 = null;

                    foreach (List <Vertex> s in segments)
                    {
                        if (s.Contains(e.Start))
                        {
                            segment1 = s;
                        }
                        else if (s.Contains(e.End))
                        {
                            segment2 = s;
                        }
                    }

                    if (segment2 == null || segment1 == null)
                    {
                        throw new Exception("One of segments is references null");
                    }

                    Merge(segments, segment1, segment2);
                }

                await ShowSegments(segments, le, tredges);
            }

            MessageBox.Show("Остовное дерево найдено!");
        }