예제 #1
0
        public PrimMST(IGraph <TWeight> graph)
        {
            G        = graph;
            ipq      = new IndexMinHeap <TWeight>(G.V);
            marked   = new bool[G.V];
            MSTEdges = new List <Edge <TWeight> >();
            EdgeTo   = new Edge <TWeight> [G.V];

            // Prim
            Visit(0);
            while (!ipq.IsEmpty())
            {
                var v = ipq.ExtractMinIndex();
                if (EdgeTo[v] == null)
                {
                    continue;
                }
                MSTEdges.Add(EdgeTo[v]);
                Visit(v);
            }

            var value     = 0.0;
            var converter = TypeDescriptor.GetConverter(typeof(TWeight));

            foreach (var edge in MSTEdges)
            {
                value += (double)converter.ConvertTo(edge.Weight, typeof(double));
            }
            MSTWeight = (TWeight)converter.ConvertTo(value, typeof(TWeight));
        }
예제 #2
0
        // X - set of explored vertices of graph G
        // V-X - set of unexplored vertices of graph G
        //
        // Invariant.
        //     The key of a vertex w belongs to V-X is the min Dijkstra score of an edge with tail v belongs to X
        //     and head w, or +infinity if no such edge exists.
        //     key(w) = min len(v) + l(vw)
        //
        // DijkstraSearch(graph G, vertex s):
        //     // Initialization
        //     X = empty set
        //     H = empty min heap
        //     key(s) = 0
        //     for each vertex V in G.vertices do: key(V) = +infinity
        //     for each vertex V in G.vertices do: H.Insert(V)
        //     // Main loop
        //     while H is not empty do:
        //         w* = H.ExtractMin()
        //         X.Add(w*)
        //         len(w*) = key(w*)
        //         // Update Heap to maintain Invariant
        //         for every edge(w*, y) do:
        //             H.Delete(y)     // Delete: given a heap H and a pointer to an object y in H, delete y from H.
        //             key(y) = min {key(y), len(w*) + l(w*y)}
        //             H.Insert(y)
        public static int[] DijkstraMinHeap(IDirectedWeightedGraph <int> weightedGraph, int startVertex)
        {
            var minHeap          = new IndexMinHeap <int>(weightedGraph.VerticesCount);
            var exploredVertices = new HashSet <int> {
                startVertex
            };
            var len = new int[weightedGraph.VerticesCount + 1];

            for (int i = 1; i <= weightedGraph.VerticesCount; i++)
            {
                var score = i == startVertex ? 0 : 1000000;
                len[i] = score;
                minHeap.Insert(i, score);
            }

            while (!minHeap.IsEmpty())
            {
                int u = minHeap.GetMin();
                len[u] = minHeap.GetItemKey(u);
                minHeap.ExtractMin();
                exploredVertices.Add(u);

                foreach ((int v, int weight) in weightedGraph.GetAdjacentVertices(u))
                {
                    if (!exploredVertices.Contains(v))
                    {
                        if (len[v] > len[u] + weight)
                        {
                            int vKey     = minHeap.GetItemKey(v);
                            int newScore = Math.Min(len[u] + weight, vKey);
                            // can use (minHeap.Delete + minHeap.Insert) instead of DecreaseKey
                            // but this would be less effective
                            minHeap.DecreaseKey(v, newScore);
                            len[v] = newScore;
                        }
                    }
                }
            }

            return(len);
        }
        public KruskalMST(IGraph <TWeight> graph)
        {
            G        = graph;
            ipq      = new IndexMinHeap <Edge <TWeight> >(2 * G.E);
            marked   = new bool[G.V];
            MSTEdges = new List <Edge <TWeight> >();

            for (var i = 0; i < G.V; i++)
            {
                foreach (Edge <TWeight> e in G.GetAdjIterator(i))
                {
                    ipq.Add(e);
                }
            }

            var uf = new UnionFind(G.V);

            while (!ipq.IsEmpty() && MSTEdges.Count < graph.V - 1)
            {
                var e = ipq.ExtractMin();
                if (uf.IsConnected(e.V, e.W))
                {
                    continue;
                }

                MSTEdges.Add(e);
                uf.UnionElements(e.V, e.W);
            }

            var value     = 0.0;
            var converter = TypeDescriptor.GetConverter(typeof(TWeight));

            foreach (var edge in MSTEdges)
            {
                value += (double)converter.ConvertTo(edge.Weight, typeof(double));
            }
            MSTWeight = (TWeight)converter.ConvertTo(value, typeof(TWeight));
        }