# Lecture 2 - Fibonacci Heap and its Application ###### tags: `Algorithm` ## Priority Queue A data structure supporting the following operations + $Insert$: insert element $x$ + $FindMin$: return minimum element + $DeleteMin$: return and delete minimum element + $DecreaseKey$: decrease key of element $x$ to $k$ ### Applications + *Dijkstra*'s shortest path algorithm ```python Maintain a priority queue Q on vertices Put s into Q with d(s)=0, mark s Repeat Delete the minimum vertex v from Q, mark v For every edge (v,w) if w is not marked if w is in Q, update the key d(w)=min{d(w),d(v)+l(v,w)} else put w in Q with d(w)=d(v)+l(v,w) Until Q is empty ``` + $n\ Insert$, $n\ DeleteMin$, $m\ DecreaseKey$ + *Prim*'s MST algorithm ```python Maintain a priority queue Q on vertices Put s into Q with d(s)=0, mark s Repeat Delete the minimum vertex v from Q, mark v For every edge (v,w) if w is not marked if w is in Q, update the key d(w)=min{d(w), l(v,w)} else put w in Q with d(w)=l(v,w) we keep track of the vertex v that gives w the minimum d(w) Until Q is empty ``` + $n\ Insert$, $n\ DeleteMin$, $m\ DecreaseKey$ + Event-driven simulation + Huffman encoding + Heapsort ## Binary Heap ### Heap A heap is a specialized tree-based data structure that satisfies the heap property + If $A$ is a parent node of $B$ then the key of node $A$ is **smaller** than the key of node $B$ + We consider **min-heap** ![](https://i.imgur.com/wfY6eog.png) ### Binary Heap #### Definition + Almost complete binary tree + Filled on all levels, except last, where filled from left to right + **Min-heap** ordered + Every child greater than (or equal to) parent ![](https://i.imgur.com/g1OyPI4.png) #### Property + Min element is in root + Heap with $N$ elements has height = $\lfloor \log_2 N\rfloor$ #### Implementation + Use an array: no need for explicit parent or child pointers + $Parent(i) = \lfloor i/2\rfloor$ + $Left(i) = 2i$ + $Right(i) = 2i+1$ + $Insert$: insert element $x$ into heap + Insert into next available slot + Bubble up until it's heap ordered + Peter principle: nodes rise to level of incompetence + $O(\log N)$ operation + $Decrease Key$: decrease key of element $x$ to $k$ + Bubble up until it's heap ordered + $O(\log N)$ operation + $Delete Min$: delete minimum element from heap + Exchange root with rightmost leaf + Bubble root down until it's heap ordered + Power struggle principle: better subordinate is promoted + $O(\log N)$ operation + $Union$ + Combine two binary heaps $H_1$ and $H_2$ into a single heap + No easy solution + $\Omega(N)$ operations apparently required + Can support fast union with fancier heaps #### Application + *Dijkstra*'s SSSP algorithm and *Prim*'s MST algorithm: $O(m\log n)$ ## Binomial Heap *(Vuillemin, 1978)* ### Binomial Tree + Recursive definition: ![](https://i.imgur.com/LBe8t5Y.png) ![](https://i.imgur.com/9cvnbGn.png) + Rank of a node $x$: the number of children of $x$ + Rank of a tree: the rank of the root of the tree + Property of $B_k$ + Number of nodes $=2^k$ + Height $= k$ + Degree of root $= k$ + Deleting root yields binomial trees $B_{k-1}, … , B_0$ + Proof: Induction on $k$ + $B_k$ has $\begin{pmatrix}k\\i\\\end{pmatrix}$ nodes at depth $i$ + Every combination of $i$ elements in $\{k-1,k-2,...,0\}$ correspond to a node in depth $i$, based on the degrees of nodes from the root to it. + For example, $k=4, i=2$ ![](https://i.imgur.com/OF9Oz0R.png) ### Definition Sequence of binomial trees that satisfy binomial heap property + Each tree is min-heap ordered + $0$ or $1$ binomial tree of each rank + If there are two trees of the same rank, then merge them ![](https://i.imgur.com/HhWU1pf.png) ### Implementation + Represent trees using left-child, right sibling pointers + Three links per node (parent, left, right) + Roots of trees connected with singly linked list + Degrees of trees strictly decreasing from left to right ![](https://i.imgur.com/KX0WmsN.png) ### Property + Min key contained in roots of $B_0, B_1, . . . , B_k$ + Contains binomial tree $B_i\iff b_i=1$ where $b_n…b_2b_1b_0$ is binary representation of $N$, since $B_i$ has $2^i$ nodes + At most $\lfloor\log_2 N\rfloor+1$ binomial trees + Height $\leq\lfloor\log_2 N\rfloor$ ![](https://i.imgur.com/TceqoGv.png) ### Operation + $Union$: create heap $H$ that is union of heaps $H'$ and $H''$ + **Mergeableheaps** + Easy if $H'$ and $H''$ are each rank kbinomial trees + Connect roots of $H'$ and $H''$ + Choose smaller key to be root of $H$ ![](https://i.imgur.com/EPNlvRk.png) + Analogous to binary addition ![](https://i.imgur.com/sTTZP5M.png) ![](https://i.imgur.com/XIyqOd1.png) + Running time: $O(\log N)$ + $DeleteMin$: delete node with minimum key in binomial heap $H$ + Find root $x$ with min key in root list of $H$, and delete ![](https://i.imgur.com/Ws36rBe.png) + $H'\leftarrow$ broken binomial trees + $H\leftarrow Union(H', H)$ ![](https://i.imgur.com/n5w59UI.png) + Running time: $O(\log N)$ + $DecreaseKey$: decrease key of node $x$ in binomial heap $H$ + Suppose $x$ is in binomial tree $B_k$ ![](https://i.imgur.com/fJD8Vya.png) + Bubble node $x$ up the tree if $x$ is too small ![](https://i.imgur.com/hju6g79.png) + Running time: $O(\log N)$ + Proportional to depth of node $x\leq\lfloor\log_2 N\rfloor$ + $Delete$: delete node $x$ in binomial heap $H$ + $DecreaseKey(x,-\infty)$ + $DeleteMin$ + Running time $O(\log N)$ + $Insert$: insert a new node $x$ into binomial heap $H$ + $H' ← MakeHeap(x)$ + $H ← Union(H', H)$ ![](https://i.imgur.com/HdpUlvz.png) + Running time: $O(\log N)$ + Sequence of $Insert$s: + Insert a new node $x$ into binomial heap $H$ + If $N=.......0_2$, then only $1$ steps + If $N=......01_2$, then only $2$ steps + If $N=.....011_2$, then only $3$ steps + $...$ + If $N=11111111_2$, then $\log_2N$ steps + Inserting $1$ item can take $\Omega(\log N)$ time + But, inserting sequence of $N$ items takes $O(N)$ time + $(N/2)(1)+(N/4)(2)+(N/8)(3)+...\leq 2N$ + Amortized analysis ## Fibonacci Heap (*Fredman and Tarjan, 1986*) ### History + Ingenious data structure and analysis + Original motivation: improve *Dijkstra*'s shortest path algorithm from $O(m\log n)$ to $O(m + n\log n)$ ### Basic idea + Similar to binomial heaps, but less rigid structure + Binomial heap: **eagerly** consolidate trees after each $Insert$ + Fibonacci heap: **lazily** defer consolidation until next $DeleteMin$ ### Definition + Set of **heap-ordered** (each parent smaller than its children) trees ![](https://i.imgur.com/OnkeVER.png) + Maintain pointer to minimum element $\to\ FindMin$ takes $O(1)$ time ![](https://i.imgur.com/0ND6Fjg.png) + Set of marked nodes (has lost one child, if it loses another child, it will be cut) ![](https://i.imgur.com/sNweZw7.png) #### Notation + $n$: number of nodes in heap + $rank(x)$: number of children of node $x$ + $rank(H)$: max rank of any node in heap $H$ + $trees(H)$: number of trees in heap $H$ + $marks(H)$ = number of marked nodes in heap $H$ ![](https://i.imgur.com/doO0TO3.png) #### Potential function + Potential of heap $H$: $\phi(H)=trees(H)+2marks(H)$ + Amortized time: actual time $+$ change of potential + Initially sum of potentials is $0$, potentials remain positive all the time + Thus, real total time $=$ total amortized time $-$ final potential + So total time is at most the total amortized time ### Operation + $Insert$ + Create a new singleton tree + Add to root list; update min pointer (if necessary) ![](https://i.imgur.com/vTmsUV7.png) + Actual cost: $O(1)$ + Change in potential: $+1$ + Amortized cost: $O(1)$ + $DeleteMin$ + $Linking$: Make larger root be a child of smaller root ![](https://i.imgur.com/BLckJLq.png) + Delete min; meld its children into root list; update min ![](https://i.imgur.com/LPpKfeg.png) ![](https://i.imgur.com/PlBdPzV.png) + Consolidate trees so that no two roots have same rank ![](https://i.imgur.com/Bg5VRT0.png) + Same as in binomial heap ![](https://i.imgur.com/dlGdb0p.png) + Actual cost: $O(rank(H))+O(trees(H))$ + $O(rank(H))$ to meld min's children into root list + $O(rank(H))+O(trees(H))$ to update min + $O(rank(H))+O(trees(H))$ to consolidate trees + Change in potential: $O(rank(H))-trees(H)$ + $trees(H')≤rank(H)+1$ since no two trees have same rank + $∆\phi(H)= trees(H')-trees(H)≤rank(H)+1-trees(H)$ + Amortized cost: $O(rank(H))$ + Is amortized cost of $O(rank(H))$ good? + Yes, if only $Insert$ and $DeleteMin$ operations + In this case, all trees are binomial trees (we only $Link$ trees of equal rank) + This implies $rank(H)\leq\log_2 n$ + We'll implement $DecreaseKey$ so that $rank(H) = O(\log n)$ + $DecreaseKey$ + Intuition for deceasing the key of node $x$ + If heap-order is not violated, just decrease the key of $x$ + Otherwise, cut tree rooted at $x$ and meld into root list + To keep trees flat: as soon as a node has its second child cut, cut it off and meld into root list and unmark it + Case $1$: heap order not violated + Decrease key of $x$ + Change heap min pointer (if necessary) ![](https://i.imgur.com/k3MlqUJ.png) + Case $2a$: heap order violated + Decrease key of $x$ ![](https://i.imgur.com/D4WUjdT.png) + Cut tree rooted at $x$, meld into root list, and unmark ![](https://i.imgur.com/oMNfWIX.png) + If parent $p$ of $x$ is unmarked (hasn't yet lost a child), mark it ![](https://i.imgur.com/SVkHKN6.png) + Case $2b$ + Decrease key of $x$ ![](https://i.imgur.com/quy6lgJ.png) + Cut tree rooted at $x$, meld into root list, and unmark ![](https://i.imgur.com/cqxhepu.png) + If parent $p$ of $x$ is unmarked (hasn't yet lost a child), mark it Otherwise, cut $p$, meld into root list, and unmark ![](https://i.imgur.com/pRaTilS.png) ![](https://i.imgur.com/FxzbmQ6.png) + And do so recursively for all ancestors that lose a second child ![](https://i.imgur.com/2ZAsqAZ.png) ![](https://i.imgur.com/hEylt6R.png) + Question: why we have a marked root node ![](https://i.imgur.com/vNdMaWU.png) ![](https://i.imgur.com/rLBJylz.png) + Actual cost: $O(c)$ + $O(1)$ time for changing the key + $O(1)$ time for each of $c$ cuts, plus melding into root list + Change in potential: $O(1)-c$ + $trees(H')=trees(H)+c$ + $marks(H') ≤ marks(H)-c+2$ + $∆\phi≤c+ 2(-c+2)=4-c$ + Amortized cost: $O(1)$ + $Union$: combine two Fibonacci heaps + Representation: root lists are circular, doubly linked lists ![](https://i.imgur.com/hCJZYLA.png) ![](https://i.imgur.com/qf8cfGW.png) + Actual cost: $O(1)$ + Change in potential: $0$ + Amortized cost: $O(1)$ + $DeleteMin$: delete node $x$ + $DecreaseKey$ of $x$ to $-∞$ + $DeleteMin$ element in heap + Amortized cost: $O(rank(H))$ + $O(1)$ amortized for $DecreaseKey$ + $O(rank(H))$ amortized for $DeleteMin$ ### Bounding the Rank #### Lemma: Fix a point in time. Let $x$ be a node, and let $y_1, …, y_k$ denote its children in the order in which they were linked to $x$. Then $$rank(y_i)\geq\begin{cases}0,& \text{if $i=1$} \\ i-2,& \text{if $i\geq1$} \end{cases}$$ + ![](https://i.imgur.com/H0Kocdg.png) + When $y_i$ was linked into $x$, $x$ had at least $i-1$ children $y_1, …, y_{i-1}$ + Since only trees of equal rank are linked, at that time $rank(y_i)=rank(x_i)≥i-1$ + Since then, $y_i$ has lost at most one child or $y_i$ would have been cut + Thus, right now $rank(y_i)≥i-2$ #### Definition: Let $F_k$ be smallest possible tree of rank $k$ satisfying property ![](https://i.imgur.com/6PjvHtH.png) ![](https://i.imgur.com/RPEidXL.png) + Solve: $F_k≥F_{k-2}+F_{k-3}+…+F_0+1$ #### Lemma (Fibonacci fact): $F_k≥\phi^k$, where $\phi=\frac{1+\sqrt5}{2}\approx 1.618$ + Induction on $k$ + Base case: $F_0 = 0$, $F_1=1$ (slightly non-standard definition) + $F_{k+2}=F_{k}+F_{k+1}\geq\phi^k+\phi^{k+1}=\phi^k(1+\phi)=\phi^k(\phi^2)=\phi^{k+2}$ #### Corollary: $rank(H)\leq\log_{\phi}n = O(\log n)$ ### Application + *Dijkstra*'s SSSP algorithm and *Prim*'s MST algorithm: $O(m+n\log n)$ ## Summary |Operation|Linked List|Binary Heap|Binomial Heap|Fibonacci Heap*| |---|---|---|---|---| |$MakeHeap$|$O(1)$|$O(1)$|$O(1)$|$O(1)$| |$isEmpty$|$O(1)$|$O(1)$|$O(1)$|$O(1)$| |$Insert$|$O(1)$|$O(\log n)$|$O(\log n)$|$O(1)$| |$DeleteMin$|$O(n)$|$O(\log n)$|$O(\log n)$|$O(\log n)$| |$DecreaseKey$|$O(n)$|$O(\log n)$|$O(\log n)$|$O(1)$| |$Delete$|$O(n)$|$O(\log n)$|$O(\log n)$|$O(\log n)$| |$Union$|$O(1)$|$O(n)$|$O(\log n)$|$O(1)$| |$FindMin$|$O(n)$|$O(1)$|$O(\log n)$|$O(1)$| $n$: number of elements in priority queue \*amortized analysis