public static IEnumerable <Tuple <TVertex, TVertex> > GetMST(UndirectedWeightedGraph <TVertex> graph) { if (graph == null) { throw new ArgumentNullException("graph", "Specify a non-null argument."); } if (graph.VertexCount == 0) { yield break; } if (ConnectedComponents <TVertex> .GetConnectedComponentsCount(graph) > 1) { throw new ArgumentException("Graph is not connected."); } TVertex source = graph.GetVertices().First(); PriorityQueue <QueueItem> queue = new PriorityQueue <QueueItem>(); Dictionary <TVertex, QueueItem> notSpanned = new Dictionary <TVertex, QueueItem>(); foreach (TVertex vertex in graph.GetVertices().Where(v => !v.Equals(source))) { double costToSpan = graph.GetEdgeWeight(source, vertex); TVertex src = costToSpan < double.PositiveInfinity ? source : default(TVertex); QueueItem item = new QueueItem(vertex, src, costToSpan); notSpanned.Add(vertex, item); queue.Enqueue(item); } List <Tuple <TVertex, TVertex> > mst = new List <Tuple <TVertex, TVertex> >(); while (!queue.IsEmpty()) { QueueItem toSpan = queue.Dequeue(); yield return(Tuple.Create(toSpan.Source, toSpan.VertexToSpan)); notSpanned.Remove(toSpan.VertexToSpan); foreach (TVertex vertex in graph.GetNeighbours(toSpan.VertexToSpan).Where(v => notSpanned.ContainsKey(v))) { QueueItem toRelax = queue.Dequeue(notSpanned[vertex]); double costToSpan = graph.GetEdgeWeight(toSpan.VertexToSpan, vertex); if (costToSpan < toRelax.CostToSpan) { toRelax.CostToSpan = costToSpan; toRelax.Source = toSpan.VertexToSpan; } queue.Enqueue(toRelax); } } }
public static IEnumerable <Tuple <TVertex, TVertex> > GetMST(UndirectedWeightedGraph <TVertex> graph) { if (graph == null) { throw new ArgumentNullException("graph", "Specify a non-null argument."); } if (graph.VertexCount == 0) { yield break; } if (ConnectedComponents <TVertex> .GetConnectedComponentsCount(graph) > 1) { throw new InvalidOperationException("Graph is not connected."); } PriorityQueue <Edge> queue = new PriorityQueue <Edge>(); UnionFind <TVertex> connectedComponents = new UnionFind <TVertex>(); foreach (TVertex vertex in graph.GetVertices()) { connectedComponents.Add(vertex); foreach (TVertex neighbour in graph.GetNeighbours(vertex)) { queue.Enqueue(new Edge(vertex, neighbour, graph.GetEdgeWeight(vertex, neighbour))); } } List <Tuple <TVertex, TVertex> > mst = new List <Tuple <TVertex, TVertex> >(); while (!queue.IsEmpty()) { Edge minCostEdge = queue.Dequeue(); if (!connectedComponents.AreConnected(minCostEdge.Vertex1, minCostEdge.Vertex2)) { yield return(Tuple.Create(minCostEdge.Vertex1, minCostEdge.Vertex2)); connectedComponents.Union(minCostEdge.Vertex1, minCostEdge.Vertex2); } } }