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); }
/// <summary> /// Gets the minimum-weight path to a goal using the A* algorithm. /// </summary> /// <remarks>Because the heuristic is not known to be consistent, we cannot use the closed set optimization.</remarks> /// <typeparam name="TNode">The type of a node.</typeparam> /// <typeparam name="TKey">The type of a node key.</typeparam> /// <param name="sources">The set of nodes from which to start the search, weighted by their initial cost.</param> /// <param name="key">The function which maps a node to its key.</param> /// <param name="next">The function which maps a node to its adjacent nodes.</param> /// <param name="goal">The goal predicate.</param> /// <param name="heuristic">The possibly-inconsistent heuristic function.</param> /// <returns>The minimum-weight path, or null if none exists.</returns> private static IWeighted <IEnumerable <TNode> > AStarInconsistent <TNode, TKey>( IEnumerable <IWeighted <TNode> > sources, Func <TNode, TKey> key, Func <TNode, IEnumerable <IWeighted <TNode> > > next, Func <TNode, bool> goal, Func <TNode, double> heuristic) { var came_from = new Dictionary <TKey, TNode>(); IPriorityQueue <double, AStarOpen <TNode> > open_queue = new PairingHeap <double, AStarOpen <TNode> >(); var open_lookup = new Dictionary <TKey, IPriorityQueueHandle <double, AStarOpen <TNode> > >(); foreach (var source in sources) { var u = source.Value; var key_u = key(u); var g_u = source.Weight; var f_u = g_u + heuristic(u); var open_u = new AStarOpen <TNode>(u, g_u); open_u.Handle = open_queue.Add(f_u, open_u); open_lookup.Add(key_u, open_u.Handle); } while (open_queue.Count > 0) { var handle_u = open_queue.Min; var u = handle_u.Value.Node; var key_u = key(u); if (goal(u)) { var path = ReconstructPath(key, came_from, u); return(new Weighted <IEnumerable <TNode> >(path, handle_u.Value.G)); } open_queue.Remove(handle_u); open_lookup.Remove(key_u); foreach (var uv in next(u)) { var v = uv.Value; var key_v = key(v); var g_v = handle_u.Value.G + uv.Weight; var f_v = g_v + heuristic(v); IPriorityQueueHandle <double, AStarOpen <TNode> > handle_v; if (open_lookup.TryGetValue(key_v, out handle_v)) { if (f_v < handle_v.Key) { open_queue.UpdateKey(handle_v, f_v); handle_v.Value.G = g_v; came_from[key_v] = u; } } else { var open_v = new AStarOpen <TNode>(v, g_v); open_v.Handle = open_queue.Add(f_v, open_v); open_lookup.Add(key_v, open_v.Handle); came_from[key_v] = u; } } } return(null); }
/// <summary> /// Gets the minimum-weight path to a goal using uniform cost search. /// </summary> /// <typeparam name="TNode">The type of a node.</typeparam> /// <typeparam name="TKey">The type of a node key.</typeparam> /// <param name="sources">The set of nodes from which to start the search, weighted by their initial cost.</param> /// <param name="key">The function which maps a node to its key.</param> /// <param name="next">The function which maps a node to its adjacent nodes.</param> /// <param name="goal">The goal predicate.</param> /// <returns>The minimum-weight path, or null if none exists.</returns> public static IWeighted <IEnumerable <TNode> > UniformCostSearch <TNode, TKey>( this IEnumerable <IWeighted <TNode> > sources, Func <TNode, TKey> key, Func <TNode, IEnumerable <IWeighted <TNode> > > next, Func <TNode, bool> goal) { var came_from = new Dictionary <TKey, TNode>(); var open_lookup = new Dictionary <TKey, IPriorityQueueHandle <double, TNode> >(); IPriorityQueue <double, TNode> open_queue = new PairingHeap <double, TNode>(); var closed = new HashSet <TKey>(); foreach (var source in sources) { var u = source.Value; var g_u = source.Weight; open_lookup.Add(key(u), open_queue.Add(g_u, u)); } while (open_queue.Count > 0) { var handle_u = open_queue.Min; var u = handle_u.Value; var key_u = key(u); var g_u = handle_u.Key; if (goal(u)) { var path = ReconstructPath(key, came_from, u); return(new Weighted <IEnumerable <TNode> >(path, g_u)); } open_lookup.Remove(key_u); open_queue.Remove(handle_u); closed.Add(key_u); foreach (var uv in next(u)) { var v = uv.Value; var key_v = key(v); if (closed.Contains(key_v)) { continue; } IPriorityQueueHandle <double, TNode> v_handle; var g_uv = g_u + uv.Weight; if (open_lookup.TryGetValue(key_v, out v_handle)) { if (g_uv < v_handle.Key) { open_queue.UpdateKey(v_handle, g_uv); came_from[key_v] = u; } } else { open_lookup.Add(key_v, open_queue.Add(g_uv, v)); came_from[key_v] = u; } } } return(null); }
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 UpdateKey(T elem, int newPrio) { heap.UpdateKey(elem, newPrio); }