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); } } }
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); } } }
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("Остовное дерево найдено!"); }