コード例 #1
0
        public void TwoValueTest()
        {
            PairingHeap <int> pairingHeap = new PairingHeap <int>((x, y) => x > y);

            pairingHeap.Insert(10);
            pairingHeap.Insert(-2);
            var value = pairingHeap.ExtractMinimum();

            Assert.Equal(-2, value.value);
            value = pairingHeap.ExtractMinimum();
            Assert.Equal(10, value.value);
        }
コード例 #2
0
        public void Max_PairingHeap_Test()
        {
            int nodeCount = 1000 * 10;

            var maxHeap = new PairingHeap <int>(SortDirection.Descending);

            for (int i = 0; i <= nodeCount; i++)
            {
                maxHeap.Insert(i);
            }

            for (int i = 0; i <= nodeCount; i++)
            {
                maxHeap.UpdateKey(i, i + 1);
            }

            //IEnumerable tests.
            Assert.AreEqual(maxHeap.Count, maxHeap.Count());

            int max = 0;

            for (int i = nodeCount; i >= 0; i--)
            {
                max = maxHeap.Extract();
                Assert.AreEqual(max, i + 1);
            }

            var rnd        = new Random();
            var testSeries = Enumerable.Range(0, nodeCount - 1).OrderBy(x => rnd.Next()).ToList();

            foreach (var item in testSeries)
            {
                maxHeap.Insert(item);
            }

            for (int i = 0; i < testSeries.Count; i++)
            {
                var incremented = testSeries[i] + rnd.Next(0, 1000);
                maxHeap.UpdateKey(testSeries[i], incremented);
                testSeries[i] = incremented;
            }

            testSeries = testSeries.OrderByDescending(x => x).ToList();

            for (int i = 0; i < nodeCount - 2; i++)
            {
                max = maxHeap.Extract();
                Assert.AreEqual(testSeries[i], max);
            }

            //IEnumerable tests.
            Assert.AreEqual(maxHeap.Count, maxHeap.Count());
        }
コード例 #3
0
        public void Min_PairingHeap_Test()
        {
            int nodeCount = 1000 * 10;

            var minHeap = new PairingHeap <int>();

            for (int i = 0; i <= nodeCount; i++)
            {
                minHeap.Insert(i);
            }

            for (int i = 0; i <= nodeCount; i++)
            {
                minHeap.UpdateKey(i, i - 1);
            }

            int min = 0;

            for (int i = 0; i <= nodeCount; i++)
            {
                min = minHeap.Extract();
                Assert.AreEqual(min, i - 1);
            }

            //IEnumerable tests.
            Assert.AreEqual(minHeap.Count, minHeap.Count());

            var rnd        = new Random();
            var testSeries = Enumerable.Range(0, nodeCount - 1).OrderBy(x => rnd.Next()).ToList();

            foreach (var item in testSeries)
            {
                minHeap.Insert(item);
            }

            for (int i = 0; i < testSeries.Count; i++)
            {
                var decremented = testSeries[i] - rnd.Next(0, 1000);
                minHeap.UpdateKey(testSeries[i], decremented);
                testSeries[i] = decremented;
            }

            testSeries.Sort();

            for (int i = 0; i < nodeCount - 2; i++)
            {
                min = minHeap.Extract();
                Assert.AreEqual(testSeries[i], min);
            }

            //IEnumerable tests.
            Assert.AreEqual(minHeap.Count, minHeap.Count());
        }
コード例 #4
0
        public void BuildMaxHeap_CreateHeap_HeapIsCheked()
        {
            var nodeCount = 1000 * 10;
            var maxHeap   = new PairingHeap <int>(Sorting.Descending);

            for (var i = 0; i <= nodeCount; i++)
            {
                maxHeap.Insert(i);
            }

            for (var i = 0; i <= nodeCount; i++)
            {
                maxHeap.UpdateKey(i, i + 1);
            }

            Assert.AreEqual(maxHeap.Count, maxHeap.Count);

            var max = 0;

            for (var i = nodeCount; i >= 0; i--)
            {
                max = maxHeap.Extract();
                Assert.AreEqual(max, i + 1);
            }

            var rnd        = new Random();
            var testSeries = Enumerable.Range(0, nodeCount - 1).OrderBy(_ => rnd.Next()).ToList();

            foreach (var item in testSeries)
            {
                maxHeap.Insert(item);
            }

            for (var i = 0; i < testSeries.Count; i++)
            {
                var incremented = testSeries[i] + rnd.Next(0, 1000);
                maxHeap.UpdateKey(testSeries[i], incremented);
                testSeries[i] = incremented;
            }

            testSeries = testSeries.OrderByDescending(x => x).ToList();
            for (var i = 0; i < nodeCount - 2; i++)
            {
                max = maxHeap.Extract();
                Assert.AreEqual(testSeries[i], max);
            }

            Assert.AreEqual(maxHeap.Count, maxHeap.Count);
        }
コード例 #5
0
        public static (bool connected, Graph tree) Prim(this Graph g, int startingVertex = 0)
        {
            if (g.Directed)
            {
                throw new WrongGraphException("Graph must be an undirected graph");
            }

            if (startingVertex < 0 || startingVertex >= g.VerticesCount)
            {
                throw new ArgumentOutOfRangeException("startingVertex");
            }

            Graph tree = g.IsolatedGraph(g.Directed);
            PairingHeap <Edge> queue = new PairingHeap <Edge>((x, y) => x.Weight > y.Weight);

            UnionFind unionFind = new UnionFind(g.VerticesCount);

            foreach (var e in g.GetEdgesFrom(startingVertex))
            {
                queue.Insert(e);
            }

            int c = 0;

            while (true)
            {
                if (queue.IsEmpty() || c == g.VerticesCount - 1)
                {
                    return(c == g.VerticesCount - 1 ? true : false, tree);
                }

                var e = queue.ExtractMinimum();

                if (unionFind.FindParent(e.value.From) != unionFind.FindParent(e.value.To))
                {
                    tree.AddEdge(e.value);

                    unionFind.Union(e.value.From, e.value.To);

                    foreach (var f in g.GetEdgesFrom(e.value.To))
                    {
                        queue.Insert(f);
                    }

                    c++;
                }
            }
        }
コード例 #6
0
    // Test program
    public static void Main(string[] args)
    {
        PairingHeap <int> h = new PairingHeap <int>( );
        int numItems        = 10000;
        int i = 37;
        int j;

        Console.WriteLine("Checking; no bad output is good");
        for (i = 37; i != 0; i = (i + 37) % numItems)
        {
            h.Insert(i);
        }
        for (i = 1; i < numItems; i++)
        {
            if (h.DeleteMin( ) != i)
            {
                Console.WriteLine("Oops! " + i);
            }
        }

        List <IPriorityQueuePosition <int> > p = new List <IPriorityQueuePosition <int> >( );

        for (i = 0; i < numItems; i++)
        {
            p.Add(null);
        }

        for (i = 0, j = numItems / 2; i < numItems; i++, j = (j + 71) % numItems)
        {
            p[j] = h.Insert(j + numItems);
        }
        for (i = 0, j = numItems / 2; i < numItems; i++, j = (j + 53) % numItems)
        {
            h.DecreaseKey(p[j], p[j].GetValue( ) - numItems);
        }
        i = -1;
        while (!h.IsEmpty( ))
        {
            if (h.DeleteMin( ) != ++i)
            {
                Console.WriteLine("Oops! " + i + " ");
            }
        }
        Console.WriteLine("Check completed");
    }
コード例 #7
0
        public void BuildMinHeap_UpdateBadNode_ThrowException()
        {
            var minHeap = new PairingHeap <int>();

            minHeap.Insert(10);

            Action act = () => minHeap.UpdateKey(10, 11);

            act.Should().Throw <ArgumentException>();
        }
コード例 #8
0
        public void BuildMinHeap_CheckEnumerator_NotThrowOnEnumerate()
        {
            var minHeap = new PairingHeap <int>();

            minHeap.Insert(1);

            var items = minHeap.ToList();

            items.Should().HaveCount(1);
        }
コード例 #9
0
        // Single-source weighted shortest-path algorithm using pairing heaps.
        public void Dijkstra2(string startName)
        {
            IPriorityQueue <Path> pq = new PairingHeap <Path>();

            Vertex start = vertexMap[startName]; // throws an exception if not found

            ClearAll();
            start.pos  = pq.Insert(new Path(start, 0));
            start.dist = 0;

            while (!pq.IsEmpty())
            {
                Path   vrec = pq.DeleteMin();
                Vertex v    = vrec.dest;

                foreach (Edge e in v.adj)
                {
                    Vertex w   = e.dest;
                    double cvw = e.cost;

                    if (cvw < 0)
                    {
                        throw new GraphException("Graph has negative edges");
                    }

                    if (w.dist > v.dist + cvw)
                    {
                        w.dist = v.dist + cvw;
                        w.prev = v;

                        Path newVal = new Path(w, w.dist);
                        if (w.pos == null)
                        {
                            w.pos = pq.Insert(newVal);
                        }
                        else
                        {
                            pq.DecreaseKey(w.pos, newVal);
                        }
                    }
                }
            }
        }
コード例 #10
0
        public void BuildMinHeap_CheckEnumerable_NotThrowOnEnumerate()
        {
            var minHeap = new PairingHeap <int>();

            minHeap.Insert(1);

            foreach (var node in (IEnumerable)minHeap)
            {
                node.Should().NotBe(null);
            }
        }
コード例 #11
0
        public void NValueTest(int n)
        {
            PairingHeap <int> pairingHeap = new PairingHeap <int>((x, y) => x > y);
            List <int>        lista       = new List <int>();

            Random random = new Random();

            for (int i = 0; i < n; i++)
            {
                int value = random.Next() % n * (0 == random.Next() % 2 ? -1 : 1);
                lista.Add(value);
                pairingHeap.Insert(value);
            }

            lista.Sort();

            for (int i = 0; i < n; i++)
            {
                var value = pairingHeap.ExtractMinimum();
                Assert.Equal(lista[i], value.value);
            }
        }
コード例 #12
0
        public static (bool connected, Graph tree) Kruskal(this Graph g)
        {
            if (g.Directed)
            {
                throw new WrongGraphException("Graph must be an undirected graph");
            }

            Graph tree = g.IsolatedGraph(g.Directed);
            PairingHeap <Edge> queue = new PairingHeap <Edge>((x, y) => x.Weight > y.Weight);

            UnionFind unionFind = new UnionFind(g.VerticesCount);

            for (int i = 0; i < g.VerticesCount; i++)
            {
                foreach (var e in g.GetEdgesFrom(i))
                {
                    queue.Insert(e);
                }
            }

            int c = 0;

            while (true)
            {
                if (queue.IsEmpty() || c == g.VerticesCount - 1)
                {
                    return(c == g.VerticesCount - 1 ? true : false, tree);
                }

                var e = queue.ExtractMinimum();

                if (unionFind.FindParent(e.value.From) != unionFind.FindParent(e.value.To))
                {
                    tree.AddEdge(e.value);
                    unionFind.Union(e.value.From, e.value.To);
                    c++;
                }
            }
        }
コード例 #13
0
        /**
         * Pred replikaciou sa naplni parovacia halda, z ktorej su vyberane casy prichdovo. V pripade ak nie je zvolena moznost skorsich prichodov, je
         * pomocou multipliera generovany cas prichodu pacienta bez skorsieho prichodu. V pripade ak vyjde, ze v nahodnom pokuse, ze dany pacient sa nedostvil
         * tak sa multiplier zvysi o 1 a po tom co dojde k neuspesnemu nahodnemu pokusu je multiplierom vynasobeny casovy rozostup medzi pacientami a je
         * aktualizovany cas objednania.
         */
        override public void PrepareReplication()
        {
            base.PrepareReplication();
            // Setup component for the next replication
            var sim = MySim as VacCenterSimulation;

            _generatorPravdepodobnosti = new OSPRNG.UniformContinuousRNG(0, 1, sim.GeneratorNasad);
            _haldaPrichodov            = new PairingHeap <double, double>();
            MyAgent.VygenerujNepridenych();

            double casObjednania = 0;

            int    multiplier = 1;
            double casPrichodu;
            double casovyRozostup = 0;

            if (sim.AktualneParametreSimulacie.SpecialnePrichody)
            {
                double pravdepodobnost;

                _generatorPravdepodobnostiSpecifickehoPrichodu = new OSPRNG.UniformContinuousRNG(0, 1, sim.GeneratorNasad);
                _generatorPravdepodobnostiDostaveniaVCas       = new OSPRNG.UniformContinuousRNG(0, 1, sim.GeneratorNasad);
                _generatoryPrichodov = new OSPRNG.UniformContinuousRNG[] { new OSPRNG.UniformContinuousRNG(20 * 60, 60 * 60, sim.GeneratorNasad),
                                                                           new OSPRNG.UniformContinuousRNG(1 * 60, 20 * 60, sim.GeneratorNasad),
                                                                           new OSPRNG.UniformContinuousRNG(60 * 60, 80 * 60, sim.GeneratorNasad),
                                                                           new OSPRNG.UniformContinuousRNG(80 * 60, 240 * 60, sim.GeneratorNasad), };
                for (int i = 0; i < MyAgent.PocetObjednanychPacientov; ++i)
                {
                    multiplier = 1;
                    while (_generatorPravdepodobnosti.Sample() < MyAgent.PocetNepridenychPacientov / (double)MyAgent.PocetObjednanychPacientov)
                    {
                        ++multiplier;
                    }
                    casovyRozostup = multiplier * MyAgent.CasMedziPrichodmi;
                    if (casovyRozostup + casObjednania > sim.CasPrevadzkyVSekundach)
                    {
                        return;
                    }

                    casObjednania += casovyRozostup;

                    if (!(_generatorPravdepodobnostiDostaveniaVCas.Sample() < 0.1))
                    {
                        pravdepodobnost = _generatorPravdepodobnostiSpecifickehoPrichodu.Sample();
                        casPrichodu     = DajCasPrichodu(casObjednania, pravdepodobnost);
                    }
                    else
                    {
                        casPrichodu = casObjednania;
                    }

                    _haldaPrichodov.Insert(casPrichodu, casPrichodu);

                    if (casObjednania > sim.CasPrevadzkyVSekundach)
                    {
                        return;
                    }
                }
            }
            else
            {
                for (int i = 0; i < MyAgent.PocetObjednanychPacientov; ++i)
                {
                    multiplier = 1;
                    while (_generatorPravdepodobnosti.Sample() < MyAgent.PocetNepridenychPacientov / (double)MyAgent.PocetObjednanychPacientov)
                    {
                        ++multiplier;
                    }
                    casovyRozostup = multiplier * MyAgent.CasMedziPrichodmi;
                    if (casovyRozostup + casObjednania > sim.CasPrevadzkyVSekundach)
                    {
                        return;
                    }
                    casObjednania += casovyRozostup;
                    _haldaPrichodov.Insert(casObjednania, casObjednania);
                    if (casObjednania > sim.CasPrevadzkyVSekundach)
                    {
                        return;
                    }
                }
            }
        }
コード例 #14
0
        /// <summary>
        ///     Computes the shortest path between two specified vertices.
        /// </summary>
        /// <param name="startVertex">The vertex where the path should start.</param>
        /// <param name="targetVertex">The vertex where the path should end.</param>
        /// <param name="distance">The shortest distance from <paramref name="startVertex"/> to <paramref name="targetVertex"/>.</param>
        /// <returns>The shortest path, represented as a span of edges.</returns>
        /// <exception cref="ArgumentException">There is no path from <paramref name="startVertex"/> to <paramref name="targetVertex"/>.</exception>
        public ReadOnlySpan <TEdgeId> ComputeShortestPath(TVertexId startVertex, TVertexId targetVertex, out TDistance distance)
        {
            var vertices = new Dictionary <TVertexId, VertexInfo>(this._graph.Comparer);
            var queue    = new PairingHeap <TVertexId, TDistance>(this._calculator);

            var startHeapElement = queue.Insert(new(startVertex, this._calculator.Zero));
            var startVertexInfo  = new VertexInfo(this._heuristicDistanceCalculator(startVertex, targetVertex))
            {
                DistanceToVertex = this._calculator.Zero,
                HeapElement      = startHeapElement
            };

            vertices.Add(startVertex, startVertexInfo);

            while (queue.TryExtractMinimum(out var next))
            {
                var currentVertexInfo = vertices[next.Key];
                var distanceSoFar     = currentVertexInfo.DistanceToVertex;
                currentVertexInfo.HeapElement = PairingHeap <KeyValuePair <TVertexId, TDistance> > .ElementPointer.Undefined;
                if (this._graph.Equals(next.Key, targetVertex))
                {
                    distance = distanceSoFar;
                    return(this.ResolveShortestPath(startVertex, targetVertex, vertices));
                }

                var edges = this._graph.GetOutEdges(next.Key);
                foreach (var edgeId in edges)
                {
                    var target          = this._graph.GetTarget(edgeId);
                    var currentDistance = this._calculator.Add(distanceSoFar, this._graph.GetEdgeTag(edgeId));
                    if (vertices.TryGetValue(target, out var vertexInfo))
                    {
                        if (this._calculator.Compare(currentDistance, vertexInfo.DistanceToVertex) >= 0)
                        {
                            continue;
                        }

                        vertexInfo.DistanceToVertex   = currentDistance;
                        vertexInfo.ShortestPathSource = next.Key;
                        vertexInfo.ShortestPathEdge   = edgeId;
                        var priority = this._calculator.Add(currentDistance, vertexInfo.HeuristicDistanceToTarget);
                        if (vertexInfo.HeapElement.IsUndefined)
                        {
                            vertexInfo.HeapElement = queue.Insert(target, priority);
                        }
                        else
                        {
                            queue.Decrease(vertexInfo.HeapElement, priority);
                        }
                    }
                    else
                    {
                        var heuristicDistance = this._heuristicDistanceCalculator(target, targetVertex);
                        var priority          = this._calculator.Add(currentDistance, heuristicDistance);
                        var heapElement       = queue.Insert(target, priority);
                        vertexInfo = new(heuristicDistance)
                        {
                            HeapElement        = heapElement,
                            DistanceToVertex   = currentDistance,
                            ShortestPathSource = next.Key,
                            ShortestPathEdge   = edgeId
                        };
                        vertices.Add(target, vertexInfo);
                    }
                }
            }

            throw new ArgumentException("Target vertex not reachable from start vertex.", nameof(targetVertex));
        }
コード例 #15
0
ファイル: PriorityQueue.cs プロジェクト: wildrabbit/7drl-lib
 public void Enqueue(T item, int priority)
 {
     heap.Insert(item, priority);
 }