コード例 #1
0
        // delete

        /**
         * Inserts a new data element into the heap. No heap consolidation is performed at this time,
         * the new node is simply inserted into the root list of this heap.
         *
         * <p>
         * Running time: O(1) actual
         * </p>
         *
         * @param node new node to insert into heap
         * @param key key value associated with data object
         * @throws IllegalArgumentException if the node already belongs to a heap
         */
        public void insert(FibonacciHeapNode <T> node, double key)
        {
            if (node.right != null)
            {
                throw new ArgumentException("Invalid heap node");
            }

            node.key = key;

            // concatenate node into min list
            if (minNode != null)
            {
                node.left       = minNode;
                node.right      = minNode.right;
                minNode.right   = node;
                node.right.left = node;

                if (key < minNode.key)
                {
                    minNode = node;
                }
            }
            else
            {
                node.left  = node;
                node.right = node;
                minNode    = node;
            }

            nNodes++;
        }
コード例 #2
0
        /**
         * {@inheritDoc}
         */
        public V next()
        {
            if (!hasNext())
            {
                throw new Exception("NoSuchElementException");
            }

            // settle next node
            FibonacciHeapNode <QueueEntry> vNode = heap.removeMin();
            V      v         = vNode.getData().v;
            double vDistance = vNode.getKey();

            // relax edges
            foreach (E e in graph.outgoingEdgesOf(v))
            {
                V      u       = Graphs.getOppositeVertex(graph, e, v);
                double eWeight = graph.getEdgeWeight(e);
                if (eWeight < 0.0)
                {
                    throw new ArgumentException("Negative edge weight not allowed");
                }
                updateDistance(u, e, vDistance + eWeight);
            }

            return(v);
        }
コード例 #3
0
    public void Decrement(FibonacciHeapNode <T> node, T value)
    {
        int comparison = value.CompareTo(node.Value);

        if (comparison == 0)
        {
            return;
        }

        if (comparison > 0)
        {
            throw new ArgumentException("Cannot increment a node value");
        }

        node.Value = value;

        FibonacciHeapNode <T> parent = node.parent;

        if (parent != null && node < parent)
        {
            Cut(node);
            CascadinglyCut(parent);
        }

        if (node < root)
        {
            root = node;
        }
    }
コード例 #4
0
        // cut

        /**
         * Make node y a child of node x.
         *
         * <p>
         * Running time: O(1) actual
         * </p>
         *
         * @param y node to become child
         * @param x node to become parent
         */
        protected void link(FibonacciHeapNode <T> y, FibonacciHeapNode <T> x)
        {
            // remove y from root list of heap
            y.left.right = y.right;
            y.right.left = y.left;

            // make y a child of x
            y.parent = x;

            if (x.child == null)
            {
                x.child = y;
                y.right = y;
                y.left  = y;
            }
            else
            {
                y.left        = x.child;
                y.right       = x.child.right;
                x.child.right = y;
                y.right.left  = y;
            }

            // increase degree[x]
            x.degree++;

            // set mark[y] false
            y.mark = false;
        }
コード例 #5
0
        public void Insert(T value, TKey key)
        {
            var node = new FibonacciHeapNode <T, TKey>(value, key);

            Heap.Insert(node);
            HeapLookup.Add(value, node);
        }
コード例 #6
0
        /// <summary>
        ///   Adds to passed heap-ordered tree node to the list of this node's
        ///   children, increasing the rank of this node.
        /// </summary>
        /// <param name="node">the new child of this node</param>
        public void AddChild(FibonacciHeapNode <T> node)
        {
            // update the rank of this node
            this.Rank++;

            // set the parent of the new node
            node.Parent = this;

            if (this.SomeChild == null)
            {
                // new node is the only child (has no siblings)
                node.LeftSibling  = node;
                node.RightSibling = node;
            }
            else
            {
                // append new node to the right
                node.LeftSibling              = this.SomeChild;
                node.RightSibling             = this.SomeChild.RightSibling;
                node.RightSibling.LeftSibling = node;
                this.SomeChild.RightSibling   = node;
            }

            this.SomeChild = node;
        }
コード例 #7
0
        // consolidate

        /**
         * The reverse of the link operation: removes x from the child list of y. This method assumes
         * that min is non-null.
         *
         * <p>
         * Running time: O(1)
         * </p>
         *
         * @param x child of y to be removed from y's child list
         * @param y parent of x about to lose a child
         */
        protected void cut(FibonacciHeapNode <T> x, FibonacciHeapNode <T> y)
        {
            // remove x from childlist of y and decrement degree[y]
            x.left.right = x.right;
            x.right.left = x.left;
            y.degree--;

            // reset y.child if necessary
            if (y.child == x)
            {
                y.child = x.right;
            }

            if (y.degree == 0)
            {
                y.child = null;
            }

            // add x to root list of heap
            x.left        = minNode;
            x.right       = minNode.right;
            minNode.right = x;
            x.right.left  = x;

            // set parent[x] to nil
            x.parent = null;

            // set mark[x] to false
            x.mark = false;
        }
コード例 #8
0
    /// <summary>
    /// 插入新结点
    /// </summary>
    public void Insert(TElement item, TPriority priority)
    {
        FibonacciHeapNode <TElement, TPriority> node = new FibonacciHeapNode <TElement, TPriority>(item, priority);

        heap.Insert(node);
        fibonacciNodeDic[item] = node;
    }
コード例 #9
0
    private void Cut(FibonacciHeapNode <T> node)
    {
        FibonacciHeapNode <T> parent = node.parent;

        if (parent.child == node)
        {
            FibonacciHeapNode <T> newChild = node.right;
            if (newChild == node)
            {
                parent.child = null;
            }
            else
            {
                parent.child = newChild;
            }
        }

        node.Extract();
        node.parent   = null;
        node.isMarked = false;

        parent.Degree--;

        root.Concatenate(node);
    }
コード例 #10
0
        // clear

        /**
         * Decreases the key value for a heap node, given the new value to take on. The structure of the
         * heap may be changed and will not be consolidated.
         *
         * <p>
         * Running time: O(1) amortized
         * </p>
         *
         * @param x node to decrease the key of
         * @param k new key value for node x
         *
         * @exception IllegalArgumentException Thrown if k is larger than x.key value.
         */
        public void decreaseKey(FibonacciHeapNode <T> x, double k)
        {
            if (k > x.key)
            {
                throw new ArgumentException(
                          "decreaseKey() got larger key value. Current key: " + x.key + " new key: " + k);
            }

            if (x.right == null)
            {
                throw new ArgumentException("Invalid heap node");
            }

            x.key = k;

            FibonacciHeapNode <T> y = x.parent;

            if ((y != null) && (x.key < y.key))
            {
                cut(x, y);
                cascadingCut(y);
            }

            if (x.key < minNode.key)
            {
                minNode = x;
            }
        }
コード例 #11
0
ファイル: FibonacciHeap.cs プロジェクト: Neo4Net/Neo4Net
        /// <summary>
        /// Internal helper function.
        /// </summary>
        protected internal virtual void Consolidate()
        {
            // TODO: lower the size of this (log(n))
            int arraySize = NrNodes + 1;
            // arraySize = 2;
            // for ( int a = nrNodes + 1; a < 0; a /= 2 )
            // {
            // arraySize++;
            // }
            // arraySize = (int) Math.log( (double) nrNodes )+1;
            // FibonacciHeapNode[] A = (FibonacciHeapNode[]) new Object[arraySize];
            // FibonacciHeapNode[] A = new FibonacciHeapNode[arraySize];
            List <FibonacciHeapNode> nodes = new List <FibonacciHeapNode>(arraySize);

            for (int i = 0; i < arraySize; ++i)
            {
                nodes.Add(null);
            }
            IList <FibonacciHeapNode> rootNodes = new LinkedList <FibonacciHeapNode>();

            rootNodes.Add(MinimumConflict);
            for (FibonacciHeapNode n = MinimumConflict.right; !n.Equals(MinimumConflict); n = n.Right)
            {
                rootNodes.Add(n);
            }
            foreach (FibonacciHeapNode node in rootNodes)
            {
                // no longer a root node?
                if (node.Parent != null)
                {
                    continue;
                }
                int d = node.Degree;
                while (nodes[d] != null)
                {
                    FibonacciHeapNode y = nodes[d];
                    // swap?
                    if (KeyComparator.Compare(node.KeyConflict, y.KeyConflict) > 0)
                    {
                        FibonacciHeapNode tmp = node;
                        node = y;
                        y    = tmp;
                    }
                    Link(y, node);
                    nodes[d] = null;
                    ++d;
                }
                nodes[d] = node;
            }
            // throw away the root list
            MinimumConflict = null;
            // and rebuild it from A
            foreach (FibonacciHeapNode node in nodes)
            {
                if (node != null)
                {
                    InsertInRootList(node);
                }
            }
        }
コード例 #12
0
ファイル: FibonacciHeap.cs プロジェクト: Neo4Net/Neo4Net
 public FibonacciHeapNode(FibonacciHeap <KeyType> outerInstance, KeyType key) : base()
 {
     this._outerInstance = outerInstance;
     this.KeyConflict    = key;
     Left  = this;
     Right = this;
 }
コード例 #13
0
ファイル: FibonacciHeap.cs プロジェクト: Neo4Net/Neo4Net
        /// <summary>
        /// This removes and returns the entry with the highest priority. </summary>
        /// <returns> The value with the highest priority. </returns>
        public virtual KeyType ExtractMin()
        {
            if (MinimumConflict == null)
            {
                return(default(KeyType));
            }
            FibonacciHeapNode minNode = MinimumConflict;

            // move all children to root list
            if (minNode.Child != null)
            {
                FibonacciHeapNode child = minNode.Child;
                while (minNode.Equals(child.Parent))
                {
                    FibonacciHeapNode nextChild = child.Right;
                    InsertInRootList(child);
                    child = nextChild;
                }
            }
            // remove minNode from root list
            minNode.Left.right = minNode.Right;
            minNode.Right.left = minNode.Left;
            // update minimum
            if (minNode.Right.Equals(minNode))
            {
                MinimumConflict = null;
            }
            else
            {
                MinimumConflict = MinimumConflict.right;
                Consolidate();
            }
            --NrNodes;
            return(minNode.KeyConflict);
        }
コード例 #14
0
ファイル: FibonacciHeap.cs プロジェクト: Neo4Net/Neo4Net
        /// <summary>
        /// Creates the union of two heaps by absorbing the other into this one.
        /// Note: Destroys other
        /// </summary>
        public virtual void Union(FibonacciHeap <KeyType> other)
        {
            NrNodes += other.NrNodes;
            if (other.MinimumConflict == null)
            {
                return;
            }
            if (MinimumConflict == null)
            {
                MinimumConflict = other.MinimumConflict;
                return;
            }
            // swap left nodes
            FibonacciHeapNode otherLeft = other.MinimumConflict.left;

            other.MinimumConflict.left = MinimumConflict.left;
            MinimumConflict.left       = otherLeft;
            // update their right pointers
            MinimumConflict.left.right       = MinimumConflict;
            other.MinimumConflict.left.right = other.MinimumConflict;
            // get min
            if (KeyComparator.Compare(other.MinimumConflict.key, MinimumConflict.key) < 0)
            {
                MinimumConflict = other.MinimumConflict;
            }
        }
コード例 #15
0
    private void Consolidate()
    {
        Dictionary <int, FibonacciHeapNode <T> > map = new Dictionary <int, FibonacciHeapNode <T> >();

        Queue <FibonacciHeapNode <T> > q    = new Queue <FibonacciHeapNode <T> >();
        FibonacciHeapNode <T>          node = root;

        do
        {
            q.Enqueue(node);
            node = node.right;
        } while (node != root);

        while (q.Count > 0)
        {
            node = q.Peek();
            q.Dequeue();

            int degree = node.Degree;

            //LogUtility.PrintLog("FHeap", string.Format("degree = {0}: Find a node [ {1} -{2}-> ]", degree, node.value, node.degree));
            while (map.ContainsKey(degree))
            {
                FibonacciHeapNode <T> newChild = map[degree];
                //LogUtility.PrintLog("FHeap", string.Format("degree = {0}: Find another node [ {1} -{2}-> ]", degree, newChild.value, newChild.degree));
                if (newChild < node)
                {
                    //LogUtility.PrintLog("FHeap", string.Format("degree = {0}: Switch", degree));
                    FibonacciHeapNode <T> t = node;
                    node     = newChild;
                    newChild = t;
                }

                Link(node, newChild);
                //LogUtility.PrintLog("FHeap", string.Format("degree = {0}: Link [ {1} -{2}-> ] to [ {3} -{4}-> ]", degree, newChild.value, newChild.degree, node.value, node.degree));
                map.Remove(degree);
                //LogUtility.PrintLog("FHeap", string.Format("degree = {0}: Remove degree {0} from map", degree));
                degree++;
                //LogUtility.PrintLog("FHeap", string.Format("degree = {0}: Add degree", degree));
            }

            map.Add(degree, node);
        }

        FibonacciHeapNode <T> min = root;

        node = root.right;
        while (node != root)
        {
            if (node < min)
            {
                min = node;
            }

            node = node.right;
        }

        root = min;
    }
コード例 #16
0
    public void Extract()
    {
        left.right = right;
        right.left = left;

        left  = this;
        right = this;
    }
コード例 #17
0
        // decreaseKey

        /**
         * Deletes a node from the heap given the reference to the node. The trees in the heap will be
         * consolidated, if necessary. This operation may fail to remove the correct element if there
         * are nodes with key value -Infinity.
         *
         * <p>
         * Running time: O(log n) amortized
         * </p>
         *
         * @param x node to remove from heap
         */
        public void delete(FibonacciHeapNode <T> x)
        {
            // make x as small as possible
            decreaseKey(x, Double.NegativeInfinity);

            // remove the smallest, which decreases n also
            removeMin();
        }
コード例 #18
0
ファイル: FibonacciHeap.cs プロジェクト: Neo4Net/Neo4Net
        /// <summary>
        /// Inserts a new value into the heap. </summary>
        /// <param name="key">
        ///            the value to be inserted. </param>
        /// <returns> The entry made into the heap. </returns>
        public virtual FibonacciHeapNode Insert(KeyType key)
        {
            FibonacciHeapNode node = new FibonacciHeapNode(this, key);

            InsertInRootList(node);
            ++NrNodes;
            return(node);
        }
コード例 #19
0
        public T RemoveMin()
        {
            FibonacciHeapNode <T, TKey> popped = Heap.RemoveMin();

            ObjectToHeapNodeMapping.Remove(popped.Data);

            return(popped.Data);
        }
コード例 #20
0
ファイル: Utilities.cs プロジェクト: DaedalusGame/7DRL_2020
 private void GenerateNode(Point tile, double distance, double moveDist, out DijkstraTile outTile, out FibonacciHeapNode <DijkstraTile, double> outNode)
 {
     outTile = new DijkstraTile(tile, distance, moveDist);
     outNode = new FibonacciHeapNode <DijkstraTile, double>(outTile, outTile.Distance);
     Tiles.Add(tile, outTile);
     NodeMap.Add(tile, outNode);
     Heap.Insert(outNode);
 }
コード例 #21
0
        // min

        /**
         * Removes the smallest element from the heap. This will cause the trees in the heap to be
         * consolidated, if necessary.
         *
         * <p>
         * Running time: O(log n) amortized
         * </p>
         *
         * @return node with the smallest key
         */
        public FibonacciHeapNode <T> removeMin()
        {
            FibonacciHeapNode <T> z = minNode;

            if (z != null)
            {
                int numKids             = z.degree;
                FibonacciHeapNode <T> x = z.child;
                FibonacciHeapNode <T> tempRight;

                // for each child of z do...
                while (numKids > 0)
                {
                    tempRight = x.right;

                    // remove x from child list
                    x.left.right = x.right;
                    x.right.left = x.left;

                    // add x to root list of heap
                    x.left        = minNode;
                    x.right       = minNode.right;
                    minNode.right = x;
                    x.right.left  = x;

                    // set parent[x] to null
                    x.parent = null;
                    x        = tempRight;
                    numKids--;
                }

                // remove z from root list of heap
                z.left.right = z.right;
                z.right.left = z.left;

                if (z == z.right)
                {
                    minNode = null;
                }
                else
                {
                    minNode = z.right;
                    consolidate();
                }

                // decrement size of heap
                nNodes--;

                // clear z
                z.left   = null;
                z.right  = null;
                z.degree = 0;
                z.child  = null;
                z.mark   = false;
            }

            return(z);
        }
コード例 #22
0
            /// <summary>
            /// Sets the parent node.
            /// </summary>
            /// <param name="parent">The parent.</param>
            public void SetParent(FibonacciHeapNode parent)
            {
                if (this.Parent != null)
                {
                    this.Parent.Children.Remove(this);
                }

                this.Parent = parent;
            }
コード例 #23
0
        /// <summary>
        /// Moves the minimum node to the peek.
        /// </summary>
        private void MoveMinimumToPeek()
        {
            for (LinkedListNode <FibonacciHeapNode> element = this.rootList.First; element != null; element = element.Next)
            {
                FibonacciHeapNode root = element.Value;

                if (this.comparer.Compare(root.Key, this.peekLinkedListNode.Value.Key) < 0)
                {
                    this.peekLinkedListNode = element;
                }
            }
        }
コード例 #24
0
        public void Insert(T data, TKey priority)
        {
            if (ObjectToHeapNodeMapping.ContainsKey(data))
            {
                throw new ArgumentException("Fibonacci heap can't insert a node it already contains.");
            }

            var node = new FibonacciHeapNode <T, TKey>(data, priority);

            Heap.Insert(node);
            ObjectToHeapNodeMapping.Add(data, node);
        }
コード例 #25
0
        /// <summary>
        /// Flattens the specified node.
        /// </summary>
        /// <param name="node">The node.</param>
        /// <returns>The collection of flattened nodes.</returns>
        private static IEnumerable <FibonacciHeapNode> FlattenNodes(FibonacciHeapNode node)
        {
            yield return(node);

            foreach (FibonacciHeapNode child in node.Children)
            {
                foreach (FibonacciHeapNode flattenChild in FlattenNodes(child))
                {
                    yield return(flattenChild);
                }
            }
        }
コード例 #26
0
    public FibonacciHeapNode(T value)
    {
        Value = value;

        Degree   = 0;
        isMarked = false;

        left   = this;
        right  = this;
        parent = null;
        child  = null;
    }
コード例 #27
0
        public static DijkstraTile[,] Dijkstra(IEnumerable <Point> start, int width, int height, double maxDist, Func <Point, Point, double> length, Func <Point, IEnumerable <Point> > neighbors)
        {
            var dijkstraMap = new DijkstraTile[width, height];
            var nodeMap     = new FibonacciHeapNode <DijkstraTile, double> [width, height];
            var heap        = new FibonacciHeap <DijkstraTile, double>(0);

            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    Point        tile    = new Point(x, y);
                    bool         isStart = start.Contains(tile);
                    DijkstraTile dTile   = new DijkstraTile(tile, isStart ? 0 : double.PositiveInfinity, isStart ? 0 : double.PositiveInfinity);
                    var          node    = new FibonacciHeapNode <DijkstraTile, double>(dTile, dTile.Distance);
                    dijkstraMap[x, y] = dTile;
                    nodeMap[x, y]     = node;
                    heap.Insert(node);
                }
            }

            while (!heap.IsEmpty())
            {
                var node  = heap.RemoveMin();
                var dTile = node.Data;

                if (dTile.Distance >= maxDist)
                {
                    break;
                }

                foreach (var neighbor in neighbors(dTile.Tile))
                {
                    if (neighbor.X < 0 || neighbor.Y < 0 || neighbor.X >= width || neighbor.Y >= height)
                    {
                        continue;
                    }
                    var    nodeNeighbor = nodeMap[neighbor.X, neighbor.Y];
                    var    dNeighbor    = nodeNeighbor.Data;
                    double newDist      = dTile.Distance + length(dTile.Tile, dNeighbor.Tile);

                    if (newDist < dNeighbor.Distance)
                    {
                        dNeighbor.Distance     = newDist;
                        dNeighbor.Previous     = dTile;
                        dNeighbor.MoveDistance = dTile.MoveDistance + 1;
                        heap.DecreaseKey(nodeNeighbor, dNeighbor.Distance);
                    }
                }
            }

            return(dijkstraMap);
        }
コード例 #28
0
        // union

        /**
         * Creates a String representation of this Fibonacci heap.
         *
         * @return String of this.
         */
        public override string ToString()
        {
            if (minNode == null)
            {
                return("FibonacciHeap=[]");
            }

            // create a new stack and put root on it
            Stack <FibonacciHeapNode <T> > stack = new Stack <FibonacciHeapNode <T> >();

            stack.Push(minNode);

            StringBuilder buf = new StringBuilder(512);

            buf.Append("FibonacciHeap=[");

            // do a simple breadth-first traversal on the tree
            while (stack.Count != 0)
            {
                FibonacciHeapNode <T> curr = stack.Pop();
                buf.Append(curr);
                buf.Append(", ");

                if (curr.child != null)
                {
                    stack.Push(curr.child);
                }

                FibonacciHeapNode <T> start = curr;
                curr = curr.right;

                while (curr != start)
                {
                    buf.Append(curr);
                    buf.Append(", ");

                    if (curr.child != null)
                    {
                        stack.Push(curr.child);
                    }

                    curr = curr.right;
                }
            }

            buf.Append(']');

            return(buf.ToString());
        }
コード例 #29
0
    public void Concatenate(FibonacciHeapNode <T> other)
    {
        if (other == null)
        {
            return;
        }

        FibonacciHeapNode <T> node = other.left;

        left.right = other;
        other.left = left;

        left       = node;
        node.right = this;
    }
コード例 #30
0
 /// <summary>
 ///   Combines the heap-ordered tree represented by the passed root node
 ///   with the tree represented by this one. Assumes that both trees are
 ///   item-disjoint.
 /// </summary>
 /// <param name="otherTreeRoot">the root of the other tree to combine with this one</param>
 /// <returns>the root of the resulting heap-ordered tree</returns>
 public FibonacciHeapNode <T> Link(FibonacciHeapNode <T> otherTreeRoot)
 {
     if (this.Item.Key < otherTreeRoot.Item.Key)
     {
         this.AddChild(otherTreeRoot);
         otherTreeRoot.Marked = false;
         return(this);
     }
     else
     {
         otherTreeRoot.AddChild(this);
         this.Marked = false;
         return(otherTreeRoot);
     }
 }