// 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++; }
/** * {@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); }
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; } }
// 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; }
public void Insert(T value, TKey key) { var node = new FibonacciHeapNode <T, TKey>(value, key); Heap.Insert(node); HeapLookup.Add(value, node); }
/// <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; }
// 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; }
/// <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; }
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); }
// 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; } }
/// <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); } } }
public FibonacciHeapNode(FibonacciHeap <KeyType> outerInstance, KeyType key) : base() { this._outerInstance = outerInstance; this.KeyConflict = key; Left = this; Right = this; }
/// <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); }
/// <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; } }
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; }
public void Extract() { left.right = right; right.left = left; left = this; right = this; }
// 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(); }
/// <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); }
public T RemoveMin() { FibonacciHeapNode <T, TKey> popped = Heap.RemoveMin(); ObjectToHeapNodeMapping.Remove(popped.Data); return(popped.Data); }
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); }
// 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); }
/// <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; }
/// <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; } } }
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); }
/// <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); } } }
public FibonacciHeapNode(T value) { Value = value; Degree = 0; isMarked = false; left = this; right = this; parent = null; child = null; }
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); }
// 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()); }
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; }
/// <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); } }