Example #1
0
        /// <summary>
        /// Updates the degree of a node, cascading to update the degree of the
        /// parents if nessecary
        /// </summary>
        /// <param name="parentNode"></param>
        private void UpdateNodesDegree(
            FibonacciHeapHeapCell <TPriority, TValue> parentNode)
        {
            Contract.Requires(parentNode != null);

            var oldDegree = parentNode.Degree;

            parentNode.Degree =
                parentNode.Children.First != null
                    ? Max(parentNode.Children, x => x.Degree) + 1
                    : 1;

            FibonacciHeapHeapCell <TPriority, TValue> degreeMapValue;

            if (oldDegree != parentNode.Degree)
            {
                if (degreeToNode.TryGetValue(oldDegree, out degreeMapValue) && degreeMapValue == parentNode)
                {
                    degreeToNode.Remove(oldDegree);
                }
                else if (parentNode.Parent != null)
                {
                    UpdateNodesDegree(parentNode.Parent);
                }
            }
        }
Example #2
0
        /// <summary>
        /// endqueue a node
        /// </summary>
        /// <param name="Priority">node prio</param>
        /// <param name="Value">node value</param>
        /// <returns>node</returns>
        public FibonacciHeapHeapCell <TPriority, TValue> Enqueue(TPriority Priority, TValue Value)
        {
            var newNode =
                new FibonacciHeapHeapCell <TPriority, TValue>
            {
                Priority = Priority,
                Value    = Value,
                Marked   = false,
                Children = new FibonacciHeapHeapLinkedList <TPriority, TValue>(),
                Degree   = 1,
                Next     = null,
                Previous = null,
                Parent   = null,
                Removed  = false
            };

            //We don't do any book keeping or maintenance of the heap on Enqueue,
            //We just add this node to the end of the list of Heaps, updating the Next if required
            this.nodes.AddLast(newNode);
            if (next == null ||
                (this.priorityComparsion(newNode.Priority, next.Priority) * DirectionMultiplier) < 0)
            {
                next = newNode;
            }
            count++;
            return(newNode);
        }
Example #3
0
        /// <summary>
        /// Delete a cell
        /// </summary>
        /// <param name="node">node</param>
        public void Delete(FibonacciHeapHeapCell <TPriority, TValue> node)
        {
            Contract.Requires(node != null);

            ChangeKeyInternal(node, default(TPriority), true);
            Dequeue();
        }
Example #4
0
        /// <summary>
        /// Remove a cell
        /// </summary>
        /// <param name="node">node</param>
        internal void Remove(FibonacciHeapHeapCell <TPriority, TValue> node)
        {
            Contract.Requires(node != null);

            if (node.Previous != null)
            {
                node.Previous.Next = node.Next;
            }
            else if (first == node)
            {
                this.first = node.Next;
            }

            if (node.Next != null)
            {
                node.Next.Previous = node.Previous;
            }
            else if (last == node)
            {
                this.last = node.Previous;
            }

            node.Next     = null;
            node.Previous = null;
        }
Example #5
0
        /// <summary>
        /// Merge two heaps
        /// </summary>
        /// <param name="other">other heap</param>
        public void Merge(FibonacciHeap <TPriority, TValue> other)
        {
            Contract.Requires(other != null);

            if (other.Direction != this.Direction)
            {
                throw new Exception("Error: Heaps must go in the same direction when merging");
            }
            nodes.MergeLists(other.nodes);
            if ((priorityComparsion(other.Top.Priority, next.Priority) * DirectionMultiplier) < 0)
            {
                next = other.next;
            }
            count += other.Count;
        }
Example #6
0
        /// <summary>
        /// Updates the Next pointer, maintaining the heap
        /// by folding duplicate heap degrees into eachother
        /// Takes O(lg(N)) time amortized
        /// </summary>
        private void UpdateNext()
        {
            this.CompressHeap();
            var node = this.nodes.First;

            next = this.nodes.First;
            while (node != null)
            {
                if ((this.priorityComparsion(node.Priority, next.Priority) * DirectionMultiplier) < 0)
                {
                    next = node;
                }
                node = node.Next;
            }
        }
Example #7
0
        /// <summary>
        /// Add cell at the end
        /// </summary>
        /// <param name="node">cell</param>
        internal void AddLast(FibonacciHeapHeapCell <TPriority, TValue> node)
        {
            Contract.Requires(node != null);

            if (this.last != null)
            {
                this.last.Next = node;
            }
            node.Previous = this.last;
            this.last     = node;
            if (this.first == null)
            {
                this.first = node;
            }
        }
Example #8
0
        /// <summary>
        /// Given two nodes, adds the child node as a child of the parent node
        /// </summary>
        /// <param name="parentNode"></param>
        /// <param name="childNode"></param>
        private void ReduceNodes(
            FibonacciHeapHeapCell <TPriority, TValue> parentNode,
            FibonacciHeapHeapCell <TPriority, TValue> childNode)
        {
            Contract.Requires(parentNode != null);
            Contract.Requires(childNode != null);

            this.nodes.Remove(childNode);
            parentNode.Children.AddLast(childNode);
            childNode.Parent = parentNode;
            childNode.Marked = false;
            if (parentNode.Degree == childNode.Degree)
            {
                parentNode.Degree += 1;
            }
        }
Example #9
0
        /// <summary>
        /// merging two lists
        /// </summary>
        /// <param name="list">second list</param>
        internal void MergeLists(FibonacciHeapHeapLinkedList <TPriority, TValue> list)
        {
            Contract.Requires(list != null);

            if (list.First != null)
            {
                if (last != null)
                {
                    last.Next = list.first;
                }
                list.first.Previous = last;
                last = list.last;
                if (first == null)
                {
                    first = list.first;
                }
            }
        }
Example #10
0
        /// <summary>
        /// Change a key
        /// </summary>
        /// <param name="node">node</param>
        /// <param name="newKey">key</param>
        private void ChangeKeyInternal(
            FibonacciHeapHeapCell <TPriority, TValue> node,
            TPriority NewKey, bool deletingNode)
        {
            Contract.Requires(node != null);

            var delta = Math.Sign(this.priorityComparsion(node.Priority, NewKey));

            if (delta == 0)
            {
                return;
            }
            if (delta == this.DirectionMultiplier || deletingNode)
            {
                //New value is in the same direciton as the heap
                node.Priority = NewKey;
                var parentNode = node.Parent;
                if (parentNode != null && ((priorityComparsion(NewKey, node.Parent.Priority) * DirectionMultiplier) < 0 || deletingNode))
                {
                    node.Marked = false;
                    parentNode.Children.Remove(node);
                    UpdateNodesDegree(parentNode);
                    node.Parent = null;
                    nodes.AddLast(node);
                    //This loop is the cascading cut, we continue to cut
                    //ancestors of the node reduced until we hit a root
                    //or we found an unmarked ancestor
                    while (parentNode.Marked && parentNode.Parent != null)
                    {
                        parentNode.Parent.Children.Remove(parentNode);
                        UpdateNodesDegree(parentNode);
                        parentNode.Marked = false;
                        nodes.AddLast(parentNode);
                        var currentParent = parentNode;
                        parentNode           = parentNode.Parent;
                        currentParent.Parent = null;
                    }
                    if (parentNode.Parent != null)
                    {
                        //We mark this node to note that it's had a child
                        //cut from it before
                        parentNode.Marked = true;
                    }
                }
                //Update next
                if (deletingNode || (priorityComparsion(NewKey, next.Priority) * DirectionMultiplier) < 0)
                {
                    next = node;
                }
            }
            else
            {
                //New value is in opposite direction of Heap, cut all children violating heap condition
                node.Priority = NewKey;
                if (node.Children != null)
                {
                    List <FibonacciHeapHeapCell <TPriority, TValue> > toupdate = null;
                    foreach (var child in node.Children)
                    {
                        if ((priorityComparsion(node.Priority, child.Priority) * DirectionMultiplier) > 0)
                        {
                            if (toupdate == null)
                            {
                                toupdate = new List <FibonacciHeapHeapCell <TPriority, TValue> >();
                            }
                            toupdate.Add(child);
                        }
                    }

                    if (toupdate != null)
                    {
                        foreach (var child in toupdate)
                        {
                            node.Marked = true;
                            node.Children.Remove(child);
                            child.Parent = null;
                            child.Marked = false;
                            nodes.AddLast(child);
                            UpdateNodesDegree(node);
                        }
                    }
                }
                UpdateNext();
            }
        }
Example #11
0
        /// <summary>
        /// Change a key
        /// </summary>
        /// <param name="node">node</param>
        /// <param name="newKey">key</param>
        public void ChangeKey(FibonacciHeapHeapCell <TPriority, TValue> node, TPriority newKey)
        {
            Contract.Requires(node != null);

            ChangeKeyInternal(node, newKey, false);
        }
Example #12
0
 public NodeLevel(FibonacciHeapHeapCell <TPriority, TValue> node, int level)
 {
     this.Node  = node;
     this.Level = level;
 }
Example #13
0
 /// <summary>
 /// list constructor
 /// </summary>
 internal FibonacciHeapHeapLinkedList()
 {
     first = null;
     last  = null;
 }