예제 #1
0
        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);
                }
            }
        }
예제 #2
0
        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);
                }
            }
        }