예제 #1
0
        public void TestIndexMinHeap()
        {
            int    n      = 1000000;
            Random random = new Random();
            var    heap   = new IndexMinHeap <int>(n);

            for (int i = 0; i < n; i++)
            {
                heap.Add((int)(random.Next() * n));
            }

            var arr = new int[n];

            for (var i = 0; i < n; i++)
            {
                arr[i] = heap.ExtractMin();
            }

            var success = true;

            for (var i = 1; i < n; i++)
            {
                if (arr[i - 1] > arr[i])
                {
                    success = false;
                }
            }

            Assert.AreEqual(true, success);
        }
예제 #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));
        }
        static void Main(string[] args)
        {
            // 使用两种图的储存方式来读取文件
            string      fileName  = "TextG1.txt";
            SparseGraph graph     = new SparseGraph(13, false);
            ReadGraph   readGraph = new ReadGraph(graph, fileName);

            Console.WriteLine("test g1 in sparse graph ");
            graph.Show();

            Console.WriteLine();

            DenseGraph graph1     = new DenseGraph(13, false);
            ReadGraph  readGraph1 = new ReadGraph(graph1, fileName);

            Console.WriteLine("test g1 in dense graph ");

            graph1.Show();


            Console.WriteLine("===========================================");

            DenseGraph graph2     = new DenseGraph(13, false);
            ReadGraph  readGraph2 = new ReadGraph(graph2, fileName);
            Path       path       = new Path(graph2, 0);

            Console.WriteLine("test path g1 in dense graph ");

            path.ShowPath(4);


            Console.WriteLine("===========================================");

            WeightedDenseGraph <double> wgraph3    = new WeightedDenseGraph <double>(8, false);
            ReadWeightedGraph           readGraph3 = new ReadWeightedGraph(wgraph3, "testG1.txt");

            Console.WriteLine("test  in weighted dense graph ");

            wgraph3.Show();

            Console.WriteLine("===========================================");

            SparseWeightedGraph <double> wgraph4    = new SparseWeightedGraph <double>(8, false);
            ReadWeightedGraph            readGraph4 = new ReadWeightedGraph(wgraph4, "testG1.txt");

            Console.WriteLine("test  in weighted sparse graph ");

            wgraph4.Show();

            Console.WriteLine("Test MinHeap");
            int           n    = 100000;
            MinHeap <int> heap = new MinHeap <int>(n);
            Random        rand = new Random();

            for (int i = 0; i < n; i++)
            {
                heap.Add(rand.Next(n));
            }
            List <int> list = new List <int>();

            for (int i = 0; i < n; i++)
            {
                list.Add(heap.ExtractMin());
            }
            for (int i = 0; i < n - 1; i++)
            {
                if (list[i] > list[i + 1])
                {
                    throw new Exception("MinHeap error");
                }
            }


            Console.WriteLine("===========================================");
            Console.WriteLine("Test MST");

            SparseWeightedGraph <double> wgraph5    = new SparseWeightedGraph <double>(8, false);
            ReadWeightedGraph            readGraph5 = new ReadWeightedGraph(wgraph5, "testG1.txt");
            LazyPrimeMST <double>        mst        = new LazyPrimeMST <double>(wgraph5);
            List <Edge <double> >        mstPath    = mst.MstEdges();

            for (int i = 0; i < mstPath.Count; i++)
            {
                Console.WriteLine(mstPath[i]);
            }

            Console.WriteLine("Test Index MinHeap");

            IndexMinHeap <int> heap1 = new IndexMinHeap <int>(n);

            for (int i = 0; i < n; i++)
            {
                heap1.Add(i, rand.Next(n));
            }

            for (int i = 0; i < n / 2; i++)
            {
                heap1.Update(i, rand.Next(n));
            }

            List <int> list1 = new List <int>();

            for (int i = 0; i < n; i++)
            {
                list1.Add(heap1.ExtractMin());
            }

            for (int i = 0; i < n - 1; i++)
            {
                if (list1[i] > list1[i + 1])
                {
                    throw new Exception("IndexMinHeap error");
                }
            }


            Console.WriteLine("===========================================");
            Console.WriteLine("Test MST Optimization");

            SparseWeightedGraph <double> wgraph6    = new SparseWeightedGraph <double>(8, false);
            ReadWeightedGraph            readGraph6 = new ReadWeightedGraph(wgraph6, "testG1.txt");
            PrimMST <double>             mst1       = new PrimMST <double>(wgraph6);
            List <Edge <double> >        mstPath1   = mst1.MstEdges();

            for (int i = 0; i < mstPath1.Count; i++)
            {
                Console.WriteLine(mstPath1[i]);
            }
        }