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); }
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()); }
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()); }
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); }
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++; } } }
// 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"); }
public void BuildMinHeap_UpdateBadNode_ThrowException() { var minHeap = new PairingHeap <int>(); minHeap.Insert(10); Action act = () => minHeap.UpdateKey(10, 11); act.Should().Throw <ArgumentException>(); }
public void BuildMinHeap_CheckEnumerator_NotThrowOnEnumerate() { var minHeap = new PairingHeap <int>(); minHeap.Insert(1); var items = minHeap.ToList(); items.Should().HaveCount(1); }
// 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); } } } } }
public void BuildMinHeap_CheckEnumerable_NotThrowOnEnumerate() { var minHeap = new PairingHeap <int>(); minHeap.Insert(1); foreach (var node in (IEnumerable)minHeap) { node.Should().NotBe(null); } }
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); } }
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++; } } }
/** * 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; } } } }
/// <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)); }
public void Enqueue(T item, int priority) { heap.Insert(item, priority); }