Пример #1
0
 public static void InsertRange <T>(this FibonacciHeap <T> heap, IEnumerable <FibonacciHeapNode <T> > enumerable)
 {
     foreach (var item in enumerable)
     {
         heap.Insert(item);
     }
 }
Пример #2
0
        public static int Dijkstra(Vertex from, Vertex to, Graph graph)
        {
            HashSet<Vertex> visited = new HashSet<Vertex>();
            Dictionary<Vertex, FibonacciHeap<int, Vertex>.Node> nodes = new Dictionary<Vertex, FibonacciHeap<int, Vertex>.Node>();
            FibonacciHeap<int, Vertex> labels = new FibonacciHeap<int, Vertex>();
            // Initialize labels.
            foreach (var vertex in graph.Vertices)
            {
                var n = labels.Add(vertex == from ? 0 : int.MaxValue, vertex);
                nodes.Add(vertex, n);
            }

            int currentLabel = int.MaxValue;
            while (!visited.Contains(to))
            {
                var currentNode = labels.ExtractMin();
                var current = currentNode.Value;
                currentLabel = currentNode.Key;

                // Consider all edges ending in unvisited neighbours
                var edges =
                    graph.GetEdgesForVertex(current).Where(x => !visited.Contains(x.Other(current)));
                // Update labels on the other end.
                foreach (var edge in edges)
                {
                    if (currentNode.Key + edge.Cost < nodes[edge.Other(current)].Key)
                        labels.DecreaseKey(nodes[edge.Other(current)], currentNode.Key + edge.Cost);
                }

                visited.Add(current);
            }

            return currentLabel;
        }
Пример #3
0
    public IList <ILevelTile> CalculatePath(ILevelTile from, ILevelTile to)
    {
        target       = to;
        openNodes    = new FibonacciHeap <float>();
        closedNodes  = new HashSet <AStarNode>();
        tilesToNodes = new Dictionary <ILevelTile, AStarNode>();

        AStarNode startNode = new AStarNode(from, heuristic.GetDistance(from.CenterPos, to.CenterPos));

        startNode.cost = 0;
        tilesToNodes.Add(from, startNode);
        openNodes.Insert(startNode);

        do
        {
            AStarNode currNode = (AStarNode)openNodes.ExtractMin();
            if (currNode.tile.Equals(to))
            {
                return(GetPathToNode(currNode));
            }

            closedNodes.Add(currNode);

            ExpandNode(currNode);
        } while (openNodes.IsEmpty() == false);

        // No path found
        return(null);
    }
Пример #4
0
        static void TestCase4()
        {
            var random = new Random();
            var myHeap = new FibonacciHeap<double>(int.MinValue, Comparer<double>.Default);
            var thirdPartyHeap = new FastPriorityQueue<FastPriorityQueueNode>(1000);

            for (var i = 0; i < 1000; i++)
            {
                if (random.Next(3) == 0 && thirdPartyHeap.Any())
                {
                    var myResult = myHeap.ExtractMin();
                    var otherResult = thirdPartyHeap.Dequeue();
                    Assert(myResult.Item1);
                    Assert(Math.Abs(myResult.Item2 - otherResult.Priority) < double.Epsilon);
                }
                else
                {
                    var value = random.NextDouble()*10;
                    myHeap.Insert(value);
                    thirdPartyHeap.Enqueue(new FastPriorityQueueNode(), value);
                }
            }

            while (thirdPartyHeap.Any())
            {
                var myResult = myHeap.ExtractMin();
                var otherResult = thirdPartyHeap.Dequeue();
                Assert(myResult.Item1);
                Assert(Math.Abs(myResult.Item2 - otherResult.Priority) < double.Epsilon);
            }
        }
        public void FibonacciHeapMergeTestMinHeaps()
        {
            // create two minheaps based on the priority value of the elements.
            FibonacciHeap <HeapElement> heap1 = new FibonacciHeap <HeapElement>((a, b) => a.Priority.CompareTo(b.Priority), true);
            FibonacciHeap <HeapElement> heap2 = new FibonacciHeap <HeapElement>((a, b) => a.Priority.CompareTo(b.Priority), true);

            FillHeap(heap1, 100);
            FillHeap(heap2, 100);
            Assert.AreEqual(100, heap1.Count);
            Assert.AreEqual(100, heap2.Count);
            // merge heap1 into heap2. heap2 will be empty afterwards
            heap1.Merge(heap2);
            Assert.AreEqual(200, heap1.Count);
            Assert.AreEqual(0, heap2.Count);

            // check if they are inserted correctly
            HeapElement previous = heap1.ExtractRoot();
            HeapElement current  = heap1.ExtractRoot();

            while (current != null)
            {
                Assert.IsTrue(previous.Priority <= current.Priority);
                previous = current;
                current  = heap1.ExtractRoot();
            }
            // heap1 should be empty as well
            Assert.AreEqual(0, heap1.Count);
        }
        public void FibonacciHeapUpdateKeyMinHeap()
        {
            FibonacciHeap <HeapElement> heap = new FibonacciHeap <HeapElement>((a, b) => a.Priority.CompareTo(b.Priority), true);

            FillHeap(heap, 100);
            Assert.AreEqual(100, heap.Count);

            // add new element. Give it a priority of 50
            HeapElement element = new HeapElement(50, "Value: 50");

            heap.Insert(element);
            Assert.AreEqual(101, heap.Count);

            // update key to 10, using an action lambda
            heap.UpdateKey(element, (a, b) => a.Priority = b, 10);
            Assert.AreEqual(10, element.Priority);

            // check if the heap is still correct
            HeapElement previous = heap.ExtractRoot();
            HeapElement current  = heap.ExtractRoot();

            while (current != null)
            {
                Assert.IsTrue(previous.Priority <= current.Priority);
                previous = current;
                current  = heap.ExtractRoot();
            }
            // heap should be empty
            Assert.AreEqual(0, heap.Count);
        }
        public static void DecreaseKey_EmptyHeap_ThrowsCorrectException()
        {
            var heap = new FibonacciHeap <int>();
            var item = new FHeapNode <int>(1);

            Assert.Throws <ArgumentException>(() => heap.DecreaseKey(item, 0));
        }
        public static void DecreaseKey_TryIncreaseKey_ThrowsCorrectException()
        {
            var heap = new FibonacciHeap <int>();
            var item = heap.Push(1);

            Assert.Throws <InvalidOperationException>(() => heap.DecreaseKey(item, 2));
        }
Пример #9
0
        public void DeleteKey()
        {
            var heap  = new FibonacciHeap <int, string>(HeapDirection.Increasing);
            int count = 0;
            var cells = new Dictionary <int, FibonacciHeapCell <int, string> >();

            for (int i = 0; i < 10; ++i)
            {
                cells.Add(i, heap.Enqueue(i, i.ToString()));
                ++count;
            }

            int?lastValue = null;

            heap.Dequeue();
            FibonacciHeapCell <int, string> deletedCell = cells[8];

            heap.Delete(deletedCell);
            count -= 2;
            foreach (KeyValuePair <int, string> value in heap.GetDestructiveEnumerator())
            {
                if (lastValue is null)
                {
                    lastValue = value.Key;
                }

                Assert.IsFalse(lastValue > value.Key, "Heap condition has been violated.");
                Assert.AreNotEqual(deletedCell, value, "Found item that was deleted.");
                lastValue = value.Key;
                --count;
            }
            Assert.AreEqual(0, count, "Not all elements enqueued were dequeued.");
        }
Пример #10
0
        public static void Union_NonEmptyHeap_ReturnsSortedOrder()
        {
            var oddHeap = new FibonacciHeap <int>();

            for (int i = 1; i < 10; i += 2)
            {
                oddHeap.Push(i);
            }

            var evenHeap = new FibonacciHeap <int>();

            for (int i = 0; i < 10; i += 2)
            {
                evenHeap.Push(i);
            }

            oddHeap.Union(evenHeap);

            for (int i = 0; i < 10; i++)
            {
                Assert.AreEqual(i, oddHeap.Pop());
            }

            Assert.Zero(oddHeap.Count);
            Assert.Zero(evenHeap.Count);
        }
Пример #11
0
        public void DecreaseKeyOnIncreasing()
        {
            var heap  = new FibonacciHeap <int, string>(HeapDirection.Increasing);
            int count = 0;
            var cells = new Dictionary <int, FibonacciHeapCell <int, string> >();

            for (int i = 0; i < 10; ++i)
            {
                cells.Add(i, heap.Enqueue(i, i.ToString()));
                ++count;
            }

            int?lastValue = null;

            heap.ChangeKey(cells[9], -1);
            foreach (KeyValuePair <int, string> value in heap.GetDestructiveEnumerator())
            {
                if (lastValue is null)
                {
                    lastValue = value.Key;
                }

                if (lastValue > value.Key)
                {
                    Assert.Fail("Heap condition has been violated.");
                }

                lastValue = value.Key;
                --count;
            }

            Assert.AreEqual(0, count, "Not all elements enqueued were dequeued.");
        }
Пример #12
0
        public void SimpleEnqueueDequeDecreasing()
        {
            var heap  = new FibonacciHeap <int, string>(HeapDirection.Decreasing);
            int count = 0;

            for (int i = 0; i < 10; ++i)
            {
                heap.Enqueue(i, i.ToString());
                ++count;
            }

            int?lastValue = null;

            foreach (KeyValuePair <int, string> value in heap.GetDestructiveEnumerator())
            {
                if (lastValue is null)
                {
                    lastValue = value.Key;
                }

                if (lastValue < value.Key)
                {
                    Assert.Fail("Heap condition has been violated.");
                }

                lastValue = value.Key;
                --count;
            }
            Assert.AreEqual(0, count, "Not all elements enqueued were dequeued.");
        }
Пример #13
0
        public void Merge()
        {
            var heap  = new FibonacciHeap <int, string>(HeapDirection.Increasing);
            var heap2 = new FibonacciHeap <int, string>(HeapDirection.Increasing);
            int count = 0;

            for (int i = 11; i > 0; --i)
            {
                heap.Enqueue(i, i.ToString());
                heap2.Enqueue(i * 11, i.ToString());
                count += 2;
            }

            heap2.Merge(heap);

            int?lastValue = null;

            foreach (KeyValuePair <int, string> value in heap2.GetDestructiveEnumerator())
            {
                if (lastValue is null)
                {
                    lastValue = value.Key;
                }

                if (lastValue > value.Key)
                {
                    Assert.Fail("Heap condition has been violated.");
                }

                lastValue = value.Key;
                --count;
            }
            Assert.AreEqual(0, count, "Not all elements enqueued were dequeued.");
        }
        static void Main(string[] args)
        {
            var heap = new FibonacciHeap<int, int>();
            heap.Insert(3, 3);
            heap.Insert(8, 8);
            heap.Insert(9, 9);
            heap.Insert(11, 11);

            heap.Insert(14, 14);
            heap.Insert(38, 38);
            heap.Insert(38, 49);
            heap.Insert(3, 56);
            heap.Insert(38, 18);
            heap.Insert(38, 17);
            heap.Insert(3, 4);

            //heap.Insert(3, 3);
            //heap.Insert(8, 8);
            //heap.Insert(9, 9);
            //heap.Insert(11, 11);
            
            //heap.Insert(14, 14);
            //heap.Insert(38, 38);
            //heap.Insert(49, 49);
            //heap.Insert(56, 56);
            //heap.Insert(18, 18);
            //heap.Insert(17, 17);
            //heap.Insert(4, 4);
            int len = heap.Count;
            for (int i = 0; i < len; i++)
            {
                var min = heap.DeleteMin();
                Console.WriteLine(min);
            }
        }
Пример #15
0
        public void IncreasingIncreaseKeyCascadeCut()
        {
            var heap  = new FibonacciHeap <int, string>(HeapDirection.Increasing);
            int count = 0;
            var cells = new Dictionary <int, FibonacciHeapCell <int, string> >();

            for (int i = 0; i < 10; ++i)
            {
                cells.Add(i, heap.Enqueue(i, i.ToString()));
                ++count;
            }

            int lastValue = heap.Top.Priority;

            heap.Dequeue();
            --count;
            heap.ChangeKey(cells[5], 10);
            foreach (KeyValuePair <int, string> value in heap.GetDestructiveEnumerator())
            {
                if (lastValue > value.Key)
                {
                    Assert.Fail($"Heap condition has been violated: {lastValue} > {value.Key}");
                }

                lastValue = value.Key;
                --count;
            }
            Assert.AreEqual(0, count, "Not all elements enqueued were dequeued.");
        }
Пример #16
0
 public static void Print <TNode, TKey, TValue>([NotNull] this FibonacciHeap <TNode, TKey, TValue> thisValue)
     where TNode : FibonacciNode <TNode, TKey, TValue>
 {
     Console.WriteLine();
     Console.WriteLine("Count: " + thisValue.Count);
     Console.WriteLine();
     thisValue.WriteTo(Console.Out);
 }
        public void Count_1Node_1Count()
        {
            var fh = new FibonacciHeap <int>();

            fh.Push(7);

            Assert.AreEqual(1, fh.Count);
        }
Пример #18
0
        public void Peek_1Node_CorrectValue()
        {
            var fh = new FibonacciHeap <int>();

            fh.Push(3);

            Assert.AreEqual(3, fh.Peek());
        }
        /// <summary>
        /// Implementation of uniform-cost search algorithm using a Fibonacci heap data structure to minimize computing times
        /// </summary>
        /// <param name="source">The node on which to start the search</param>
        /// <param name="destination">The node we try to find the shortest path to, starting from source</param>
        public List <int> LeastCostPath(int source, int destination)
        {
            var Predecessor = new Dictionary <int, int>();
            var Distance    = new Dictionary <int, double>();
            var Frontier    = new FibonacciHeap <int, double>(0);

            Frontier.Insert(new FibonacciHeapNode <int, double>(source, 0));
            var Explored = new List <int>();

            Predecessor.Add(source, -1); //value of -1 indicates this node has no predecessors

            while (true)
            {
                if (Frontier.IsEmpty())
                {
                    throw new Exception("LeastCostPath: Failed to find path between source (" + source + ") and destination (" + destination + ").");
                }

                var minNode = Frontier.RemoveMin();
                if (minNode.Data == destination)
                {
                    List <int> LCP = new List <int> {
                        minNode.Data
                    };
                    int pred = Predecessor[minNode.Data];
                    while (pred != -1)
                    {
                        LCP.Add(pred);
                        pred = Predecessor[pred];
                    }
                    LCP.Reverse();
                    return(LCP);
                }

                Explored.Add(minNode.Data);
                foreach (int neighbor in this.GetNeighbors(minNode.Data))
                {
                    if (!Explored.Contains(neighbor))
                    {
                        var neighborCost = minNode.Key + AdjacencyMatrix[minNode.Data, neighbor];
                        Frontier.Insert(new FibonacciHeapNode <int, double>(neighbor, neighborCost));
                        if (Distance.TryGetValue(neighbor, out double cost))
                        {
                            if (neighborCost < cost)
                            {
                                Predecessor[neighbor] = minNode.Data;
                                Distance[neighbor]    = neighborCost;
                            }
                        }
                        else
                        {
                            Predecessor.Add(neighbor, minNode.Data);
                            Distance.Add(neighbor, neighborCost);
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Implementation of Yen's algorithm which finds the shortest path between nodes, and then the
        /// K-1 shortest deviations from this path. Paths returned will be simple and loopless
        /// </summary>
        /// <param name="K">The number of shortest paths to find.</param>
        /// <param name="source">The node on which to start the search</param>
        /// <param name="destination">The node we try to find the shortest path to, starting from source</param>
        /// <returns></returns>
        public List <List <int> > KShortestPaths(int K, int source, int destination)
        {
            List <List <int> > ShortestPaths = new List <List <int> >();
            var PotentialPaths = new FibonacciHeap <List <int>, double>(0);

            ShortestPaths.Add(LeastCostPath(source, destination));

            //now find next K-1 shortest paths
            foreach (int k in Enumerable.Range(1, K - 1))
            {
                //The spur node ranges from the first node to the next to last node in the previous k-shortest path.
                int spurNodeCount = ShortestPaths[k - 1].Count - 1;
                foreach (int i in Enumerable.Range(0, spurNodeCount))
                {
                    int               spurNode     = ShortestPaths[k - 1][i];
                    List <int>        rootPath     = ShortestPaths[k - 1].GetRange(0, i + 1);
                    PSO_WeightedGraph AlteredGraph = this.Clone();

                    //temporarily remove edges to avoid retracing our steps
                    foreach (List <int> shortPath in ShortestPaths)
                    {
                        if (rootPath.SequenceEqual(shortPath.Take(i + 1)))
                        {
                            AlteredGraph.AdjacencyMatrix[shortPath[i], shortPath[i + 1]] = 0;
                        }
                    }

                    //To avoid looping back over a previous path, we disconnect nodes in the root path (except the spur node)
                    //by setting the weights of the edges that connect them to the graph to 0
                    foreach (int x in Enumerable.Range(0, Size).Where(a => a != spurNode & rootPath.Contains(a)))
                    {
                        var v = Vector <double> .Build.Sparse(Size);

                        AlteredGraph.AdjacencyMatrix.SetColumn(x, v);
                        AlteredGraph.AdjacencyMatrix.SetRow(x, v);
                    }

                    //build spur path and connect the spur path to the root
                    List <int> spurPath = new List <int>();
                    //finding the least cost path may fail due to removing the edges above; just ignore and continue
                    try { spurPath = AlteredGraph.LeastCostPath(spurNode, destination); }
                    catch (Exception ex) { break; }

                    List <int> totalPath = rootPath;
                    totalPath.AddRange(spurPath.Where(node => node != spurNode).ToList());
                    PotentialPaths.Insert(new FibonacciHeapNode <List <int>, double>(totalPath, this.PathCost(totalPath)));
                }

                if (PotentialPaths.IsEmpty())
                {
                    break;
                }

                ShortestPaths.Add(PotentialPaths.RemoveMin().Data);
            }

            return(ShortestPaths);
        }
Пример #21
0
        public void FibonacciHeapContainsTest()
        {
            FibonacciHeap <Int32, String> heap = new FibonacciHeap <Int32, String>(this.values);

            for (Int32 number = -1000; number < 1000; number++)
            {
                heap.Contains(number).ShouldBe(this.values.Contains(new KeyValuePair <Int32, String>(number, number.ToString())));
            }
        }
        public void Count_2Node_2Count()
        {
            var fh = new FibonacciHeap <int>();

            fh.Push(7);
            fh.Push(8);

            Assert.AreEqual(2, fh.Count);
        }
 public override Node Peek()
 {
     FibonacciHeap <HeapObject> .FibonacciHeapNode fNode = Heap.Minimum;
     if (fNode == null)
     {
         return(null);
     }
     return(fNode.Key.Node);
 }
Пример #24
0
        public void Peek_2NodesSmallerLast_CorrectValue()
        {
            var fh = new FibonacciHeap <int>();

            fh.Push(3);
            fh.Push(2);

            Assert.AreEqual(2, fh.Peek());
        }
    public void EmptyHeapDecreaseKey_DoesNothing()
    {
        FibonacciHeap <int> heap = new FibonacciHeap <int>();
        FibonacciNode <int> node = new FibonacciNode <int>(3);

        heap.DecreaseKey(node, 2);

        NUnit.Framework.Assert.True(heap.IsEmpty());
        NUnit.Framework.Assert.AreEqual(default(int), heap.GetMin());
    }
Пример #26
0
 public DijkstraMap(int width, int height, FibonacciHeap <DijkstraTile, double> heap, IEnumerable <Point> starts)
 {
     Heap   = heap;
     Width  = width;
     Height = height;
     foreach (var start in starts)
     {
         GenerateNode(start, 0, 0);
     }
 }
Пример #27
0
        public void ExchangeTest()
        {
            var heap  = new FibonacciHeap <int>((a, b) => a < b);
            var node1 = new FibonacciNode <int>(12);
            var node2 = new FibonacciNode <int>(11);

            heap.Exchange(ref node1, ref node2);

            Assert.AreEqual(node1.Key, 11);
        }
Пример #28
0
        public void PopTest()
        {
            // Heap
            FibonacciHeap <float, char> heap = new FibonacciHeap <float, char>();
            HashSet <float>             equalPriorirtyMinimums = new HashSet <float>()
            {
                'b', 'e', 'f', 'g'
            };

            // Check heap starts with no nodes
            Assert.AreEqual(heap.Count, 0);

            // Add collection of nodes
            HeapNode <float, char> node2 = heap.Insert(7, 'b');
            HeapNode <float, char> node1 = heap.Insert(3, 'a');
            HeapNode <float, char> node3 = heap.Insert(14, 'c');
            HeapNode <float, char> node4 = heap.Insert(35, 'd');
            HeapNode <float, char> node5 = heap.Insert(7, 'e');
            HeapNode <float, char> node6 = heap.Insert(7, 'f');
            HeapNode <float, char> node7 = heap.Insert(7, 'g');

            // Check heap has correct number of nodes
            Assert.AreEqual(heap.Count, 7);

            char minimum = heap.Pop();

            // Check returned item is the correct value, and is not still in heap
            Assert.AreEqual(minimum, 'a');
            Assert.AreNotEqual(heap.Minimum.Value, minimum);
            Assert.AreEqual(heap.Count, 6);

            // Pop a set of equal priority values, check heap outputs them all (order is undefined)
            for (int i = 0; i < equalPriorirtyMinimums.Count; i++)
            {
                minimum = heap.Pop();

                // Check returned item is the correct value, and is not still in heap
                Assert.IsTrue(equalPriorirtyMinimums.Contains(minimum));
                Assert.AreNotEqual(heap.Minimum.Value, minimum);
                Assert.AreEqual(heap.Count, 5 - i);
            }

            minimum = heap.Pop();

            // Check returned item is the correct value, and is not still in heap
            Assert.AreEqual(minimum, 'c');
            Assert.AreNotEqual(heap.Minimum.Value, minimum);
            Assert.AreEqual(heap.Count, 1);

            minimum = heap.Pop();

            // Check returned item is the correct value
            Assert.AreEqual(minimum, 'd');
            Assert.AreEqual(heap.Count, 0);
        }
Пример #29
0
        public List <(TVertex Vertex, EdgeBase <TVertex> EdgeToParent)> FindShortestPathWithDijkstra(TVertex start, TVertex end)
        {
            var vertexInfoDict = Vertices.Select(vertex => new DijkstraVertexInfo(vertex, vertex == start ? 0 : double.PositiveInfinity))
                                 .Select(info => new FibonacciHeapNode <DijkstraVertexInfo>(info, info.Distance))
                                 .ToDictionary(node => node.Data.Vertex, node => node);

            var heap = new FibonacciHeap <DijkstraVertexInfo>();

            heap.InsertRange(vertexInfoDict.Values);


            DijkstraVertexInfo endInfo = null;

            while (vertexInfoDict.Count > 0)
            {
                var curVertexInfo = heap.RemoveMin().Data;
                if (curVertexInfo.Vertex == end)
                {
                    endInfo = curVertexInfo;
                    break;
                }

                var neighborsWithEdges = GetNeighborsWithEdges(curVertexInfo.Vertex, ignoreSelfLoops: true);
                foreach (var neighborsWithEdge in neighborsWithEdges)
                {
                    if (vertexInfoDict.TryGetValue(neighborsWithEdge.Vertex, out FibonacciHeapNode <DijkstraVertexInfo> neighborNode))
                    {
                        var alt          = curVertexInfo.Distance + neighborsWithEdge.Edge.Weight ?? 1;
                        var neighborInfo = neighborNode.Data;
                        if (alt < neighborInfo.Distance)
                        {
                            heap.DecreaseKey(neighborNode, alt);
                            neighborInfo.Distance   = alt;
                            neighborInfo.Parent     = curVertexInfo;
                            neighborInfo.ParentEdge = neighborsWithEdge.Edge;
                        }
                    }
                }
            }

            if (endInfo != null)
            {
                var reslut    = new List <(TVertex Vertex, EdgeBase <TVertex> EdgeToParent)>();
                var curVertex = endInfo;
                while (curVertex != null)
                {
                    reslut.Add((curVertex.Vertex, curVertex.ParentEdge));
                    curVertex = curVertex.Parent;
                }
                reslut.Reverse();
                return(reslut);
            }

            return(null);
        }
    public void ConsolidatedHeapDecreaseKey_CorrectCuts()
    {
        FibonacciHeap <int>          heap  = new FibonacciHeap <int>();
        IList <FibonacciNode <int> > input = new List <FibonacciNode <int> >()
        {
            new FibonacciNode <int>(0),
            new FibonacciNode <int>(28),
            new FibonacciNode <int>(-13),
            new FibonacciNode <int>(80),
            new FibonacciNode <int>(3),
            new FibonacciNode <int>(7),
            new FibonacciNode <int>(-7),
            new FibonacciNode <int>(42),
            new FibonacciNode <int>(-11),
            new FibonacciNode <int>(12)
        };

        IList <int> expectedElementOrder = new List <int>()
        {
            7,
            -8,
            -11,
            12,
            -42,
            80,
            -1,
            -3,
            0
        };

        foreach (FibonacciNode <int> value in input)
        {
            heap.Insert(value);
        }
        heap.ExtractMin();

        // A decrease key with no structural changes
        heap.DecreaseKey(input[6], -8);

        // Normal cuts with parent marked
        heap.DecreaseKey(input[7], -42);
        heap.DecreaseKey(input[4], -1);

        // Double cascading cut
        heap.DecreaseKey(input[1], -3);

        IList <int> result = heap.GetAllValues();

        for (int i = 0; i < expectedElementOrder.Count; ++i)
        {
            NUnit.Framework.Assert.IsTrue(expectedElementOrder[i] == result[i]);
        }
        NUnit.Framework.Assert.IsTrue(heap.GetMin() == -42);
    }
    public void UnconsolidatedHeapContainsNull_false()
    {
        FibonacciHeap <int> heap  = new FibonacciHeap <int>();
        IList <int>         input = new List <int>()
        {
            0,
            28,
        };

        NUnit.Framework.Assert.IsFalse(heap.Contains(null));
    }
    public void UnconsolidatedHeapDecreaseKey_NoException()
    {
        FibonacciHeap <int> heap  = new FibonacciHeap <int>();
        IList <int>         input = new List <int>()
        {
            0,
            28,
        };

        heap.DecreaseKey(null, 3);
    }
    public void UnconsolidatedHeapInsertNull_Null()
    {
        FibonacciHeap <int> heap  = new FibonacciHeap <int>();
        IList <int>         input = new List <int>()
        {
            0,
            28,
        };

        NUnit.Framework.Assert.IsNull(heap.Insert(null));
    }
Пример #34
0
        public static Path DijkstraPath(Vertex from, Vertex to, Graph graph)
        {
            HashSet<Vertex> visited = new HashSet<Vertex>();
            Dictionary<Vertex, FibonacciHeap<int, Vertex>.Node> nodes =
                new Dictionary<Vertex, FibonacciHeap<int, Vertex>.Node>();
            Dictionary<Vertex, Edge> comingFrom = new Dictionary<Vertex, Edge>();
            FibonacciHeap<int, Vertex> labels = new FibonacciHeap<int, Vertex>();
            // Initialize labels.
            foreach (var vertex in graph.Vertices)
            {
                var n = labels.Add(vertex == from ? 0 : int.MaxValue, vertex);
                nodes.Add(vertex, n);
                comingFrom.Add(vertex, null);
            }

            while (!visited.Contains(to))
            {
                var currentNode = labels.ExtractMin();
                var current = currentNode.Value;

                // Consider all edges ending in unvisited neighbours
                var edges =
                    graph.GetEdgesForVertex(current).Where(x => !visited.Contains(x.Other(current)));
                // Update labels on the other end.
                foreach (var edge in edges)
                {
                    if (currentNode.Key + edge.Cost < nodes[edge.Other(current)].Key)
                    {
                        labels.DecreaseKey(nodes[edge.Other(current)], currentNode.Key + edge.Cost);
                        comingFrom[edge.Other(current)] = edge;
                    }
                }

                visited.Add(current);
            }

            // Now travel back, to find the actual path
            List<Edge> pathEdges = new List<Edge>();
            Vertex pathVertex = to;
            while (pathVertex != from)
            {
                pathEdges.Add(comingFrom[pathVertex]);
                pathVertex = comingFrom[pathVertex].Other(pathVertex);
            }

            pathEdges.Reverse();
            Path path = new Path(from);
            path.Edges.AddRange(pathEdges);
            return path;
        }
Пример #35
0
		public void FibonacciHeapUpdateKeyMinHeap()
		{
			FibonacciHeap<HeapElement> heap = new FibonacciHeap<HeapElement>((a, b) => a.Priority.CompareTo(b.Priority), true);

			FillHeap(heap, 100);
			Assert.AreEqual(100, heap.Count);

			// add new element. Give it a priority of 50
			HeapElement element = new HeapElement(50, "Value: 50");
			heap.Insert(element);
			Assert.AreEqual(101, heap.Count);

			// update key to 10, using an action lambda
			heap.UpdateKey(element, (a, b) => a.Priority = b, 10);
			Assert.AreEqual(10, element.Priority);

			// check if the heap is still correct
			HeapElement previous = heap.ExtractRoot();
			HeapElement current = heap.ExtractRoot();
			while(current != null)
			{
				Assert.IsTrue(previous.Priority <= current.Priority);
				previous = current;
				current = heap.ExtractRoot();
			}
			// heap should be empty 
			Assert.AreEqual(0, heap.Count);
		}
Пример #36
0
		public void FibonacciHeapMergeTestMinHeaps()
		{
			// create two minheaps based on the priority value of the elements. 
			FibonacciHeap<HeapElement> heap1 = new FibonacciHeap<HeapElement>((a, b) => a.Priority.CompareTo(b.Priority), true);
			FibonacciHeap<HeapElement> heap2 = new FibonacciHeap<HeapElement>((a, b) => a.Priority.CompareTo(b.Priority), true);

			FillHeap(heap1, 100);
			FillHeap(heap2, 100);
			Assert.AreEqual(100, heap1.Count);
			Assert.AreEqual(100, heap2.Count);
			// merge heap1 into heap2. heap2 will be empty afterwards
			heap1.Merge(heap2);
			Assert.AreEqual(200, heap1.Count);
			Assert.AreEqual(0, heap2.Count);

			// check if they are inserted correctly
			HeapElement previous = heap1.ExtractRoot();
			HeapElement current = heap1.ExtractRoot();
			while(current != null)
			{
				Assert.IsTrue(previous.Priority <= current.Priority);
				previous = current;
				current = heap1.ExtractRoot();
			}
			// heap1 should be empty as well
			Assert.AreEqual(0, heap1.Count);
		}
Пример #37
0
 public void SetLabelsFibonacciHeap(FibonacciHeap<int, Vertex> heap)
 {
     _dictLabels[_currentlyUsingVertex] = heap;
 }
Пример #38
0
            public void AddVertexToInterleavingDijkstra(Vertex vertex, Graph graph)
            {
                if (_verticesInSearch.Contains(vertex))
                    throw new InvalidOperationException("Can not add the vertex, because it is already added.");

                _verticesInSearch.Add(vertex);
                var labels = new FibonacciHeap<int, Vertex>();
                var nodes = new Dictionary<Vertex, FibonacciHeap<int, Vertex>.Node>();
                // Initialize labels.
                foreach (var v in graph.Vertices)
                {
                    var node = labels.Add(v == vertex ? 0 : int.MaxValue, v);
                    nodes.Add(v, node);
                }

                _dictLabels.Add(vertex, labels);
                _dictNodes.Add(vertex, nodes);
                _dictVisited.Add(vertex, new HashSet<Vertex>());
                _dictPathsfound.Add(vertex, new Dictionary<Vertex, Path>());
                _dictComingFrom.Add(vertex, new Dictionary<Vertex, Edge>());
                _dictComponent.Add(vertex, ++_internalNewComponentCount); // All vertices start in a different component.
            }
 public static FibonacciHeap<int, int> Create()
 {
     FibonacciHeap<int, int> fibonacciHeap
        = new FibonacciHeap<int, int>();
     return fibonacciHeap;
 }
Пример #40
0
        static void TestCase5()
        {
            var root1 = Node(7)
                .AddChild(Node(24)
                    .AddChild(Node(26).Marked()
                        .AddChild(Node(35)))
                    .AddChild(Node(46)))
                .AddChild(Node(17)
                    .AddChild(Node(30)))
                .AddChild(Node(23));
            var root2 = Node(18).Marked()
                .AddChild(Node(21)
                    .AddChild(Node(52)))
                .AddChild(Node(39).Marked());
            var root3 = Node(38).AddChild(Node(41));
            var heap = new FibonacciHeap<int>(int.MinValue, Comparer<int>.Default, new[] {root1, root2, root3});

            var node1 = root1.Children.ElementAt(0).Children.ElementAt(1);
            var node2 = root1.Children.ElementAt(0).Children.ElementAt(0).Children.ElementAt(0);
            heap.DecreaseKey(node1, 15);
            heap.DecreaseKey(node2, 5);

            var expRoots = new[]
            {
                15, 5, 26, 24, 7, 18, 38
            };
            var actualRoots = heap.Roots.Select(x => x.Data).ToList();
            Assert(expRoots.Length == actualRoots.Count);
            for (var i = 0; i < expRoots.Length; i++)
                Assert(actualRoots.Contains(expRoots[i]));
        }
Пример #41
0
        public static List<Path> NearestTerminals(Vertex from, Graph graph, int n)
        {
            List<Path> foundPaths = new List<Path>();
            HashSet<Vertex> visited = new HashSet<Vertex>();
            Dictionary<Vertex, FibonacciHeap<int, Vertex>.Node> nodes = new Dictionary<Vertex, FibonacciHeap<int, Vertex>.Node>();
            FibonacciHeap<int, Vertex> labels = new FibonacciHeap<int, Vertex>();
            Dictionary<Vertex, Edge> comingFrom = new Dictionary<Vertex, Edge>();

            if (graph.Terminals.Contains(from))
                foundPaths.Add(new Path(from));

            // Initialize labels.
            foreach (var vertex in graph.Vertices)
            {
                var node = labels.Add(vertex == from ? 0 : int.MaxValue, vertex);
                nodes.Add(vertex, node);
                comingFrom.Add(vertex, null);
            }

            while (!labels.IsEmpty() && foundPaths.Count < n)
            {
                var currentNode = labels.ExtractMin();
                var current = currentNode.Value;

                // Consider all edges ending in unvisited neighbours
                var edges =
                    graph.GetEdgesForVertex(current).Where(x => !visited.Contains(x.Other(current)));
                // Update labels on the other end.
                foreach (var edge in edges)
                {
                    if (currentNode.Key + edge.Cost < nodes[edge.Other(current)].Key)
                    {
                        labels.DecreaseKey(nodes[edge.Other(current)], currentNode.Key + edge.Cost);
                        comingFrom[edge.Other(current)] = edge;
                    }
                }

                visited.Add(current);

                if (graph.Terminals.Contains(current) && current != from)
                {
                    // Now travel back, to find the actual path
                    List<Edge> pathEdges = new List<Edge>();
                    Vertex pathVertex = current;
                    while (pathVertex != from)
                    {
                        pathEdges.Add(comingFrom[pathVertex]);
                        pathVertex = comingFrom[pathVertex].Other(pathVertex);
                    }

                    pathEdges.Reverse();
                    Path path = new Path(from);
                    path.Edges.AddRange(pathEdges);
                    foundPaths.Add(path);
                }
            }

            return foundPaths;
        }
Пример #42
0
 private static FibonacciHeap<int> CreateHeap(params int[] values)
 {
     var heap = new FibonacciHeap<int>(int.MinValue, Comparer<int>.Default);
     foreach(var value in values)
         heap.Insert(value);
     return heap;
 }
Пример #43
0
        public static Dictionary<Vertex, Path> DijkstraPathToAll(Vertex from, Graph graph, bool onlyTerminals)
        {
            Dictionary<Vertex, Edge> comingFrom = new Dictionary<Vertex, Edge>();
            HashSet<Vertex> visited = new HashSet<Vertex>();
            Dictionary<Vertex, FibonacciHeap<int, Vertex>.Node> nodes =
                new Dictionary<Vertex, FibonacciHeap<int, Vertex>.Node>();
            Dictionary<Vertex, Path> paths = new Dictionary<Vertex, Path>();
            FibonacciHeap<int, Vertex> labels = new FibonacciHeap<int, Vertex>();
            // Initialize labels.
            foreach (var vertex in graph.Vertices)
            {
                var n = labels.Add(vertex == from ? 0 : int.MaxValue, vertex);
                nodes.Add(vertex, n);
            }

            while (paths.Count < (onlyTerminals ? graph.Terminals.Count - 1 : graph.NumberOfVertices - 1))
            {
                var currentNode = labels.ExtractMin();
                var current = currentNode.Value;

                // Consider all edges ending in unvisited neighbours
                var edges =
                    graph.GetEdgesForVertex(current).Where(x => !visited.Contains(x.Other(current)));
                // Update labels on the other end.
                foreach (var edge in edges)
                {
                    if (currentNode.Key + edge.Cost < nodes[edge.Other(current)].Key)
                    {
                        labels.DecreaseKey(nodes[edge.Other(current)], currentNode.Key + edge.Cost);
                        comingFrom[edge.Other(current)] = edge;
                    }
                }

                visited.Add(current);
                if (current != from && (!onlyTerminals || graph.Terminals.Contains(current)))
                {
                    // Travel back the path
                    List<Edge> pathEdges = new List<Edge>();
                    Vertex pathVertex = current;
                    while (pathVertex != from)
                    {
                        pathEdges.Add(comingFrom[pathVertex]);
                        pathVertex = comingFrom[pathVertex].Other(pathVertex);
                    }

                    pathEdges.Reverse();
                    Path path = new Path(from);
                    path.Edges.AddRange(pathEdges);
                    paths[current] = path;
                }
            }

            return paths;
        }