コード例 #1
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());
        }
コード例 #2
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());
        }
コード例 #3
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);
        }
コード例 #4
0
        /// <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);
        }
コード例 #5
0
        /// <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);
        }
コード例 #6
0
        public void BuildMinHeap_UpdateBadNode_ThrowException()
        {
            var minHeap = new PairingHeap <int>();

            minHeap.Insert(10);

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

            act.Should().Throw <ArgumentException>();
        }
コード例 #7
0
ファイル: PriorityQueue.cs プロジェクト: wildrabbit/7drl-lib
 public void UpdateKey(T elem, int newPrio)
 {
     heap.UpdateKey(elem, newPrio);
 }