680 likes | 692 Vues
CSE 326: Data Structures Priority Queues (Heaps). Lecture 9: Monday, Jan 27, 2003. Not Quite Queues. Consider applications ordering CPU jobs searching for the exit in a maze emergency room admission processing Problems? short jobs should go first
E N D
CSE 326: Data Structures Priority Queues (Heaps) Lecture 9: Monday, Jan 27, 2003
Not Quite Queues • Consider applications • ordering CPU jobs • searching for the exit in a maze • emergency room admission processing • Problems? • short jobs should go first • most promising nodes should be searched first • most urgent cases should go first
Priority Queue ADT • Priority Queue operations • Priority Queue property: for two elements in the queue, x and y, if x has a lower priority value than y, x will be deleted before y create : heap insert : heap value heap findMin : heap value deleteMin : heap heap is_empty : heap boolean F(7) E(5) D(100) A(4) B(6) deleteMin insert C(3) G(9)
Applications of the Priority Q • Hold jobs for a printer in order of length • Store packets on network routers in order of urgency • Simulate events • Anything greedy
Discrete Event Simulation • An event is a pair (x,t) where x describes the event and t is time it should occur • A discrete event simulator (DES) maintains a set S of events which it intends to simulate in time order repeat { Find and remove (x0,t0) from S such that t0 is minimum; Do whatever x0 says to do; in the process new events (x1,t1)…(xk,tk) may be generated; Insert the new events into S; }
Emergency Room Simulation • Patient arrive at time t with injury of criticality C • If no patients waiting and a free doctor, assign them to doctor and create a future departure event; else put patient in the Criticality priority queue • Patient departs at time t • If someone in Criticality queue, pull out most critical and assign to doctor; create a future departure event arrive(t,c) patient generator time queue criticality (triage) queue depart(t) assignpatient to doctor arrive(t,c) depart(t)
Naïve Priority Queue Data Structures • Unsorted list: • insert: • findMin: • deleteMin: • Sorted list: • insert: • findMin: • deleteMin:
BST Tree Priority Queue Data Structure • Regular BST: • insert: • findMin: • deleteMin: • AVL Tree: • insert: • findMin: • deleteMin: 8 5 11 2 6 10 12 13 4 7 9 14 Can we do better?
Heap-order property parent’s key is less than children’s keys result: minimum is always at the top Structure property complete tree with fringe nodes packed to the left result: depth is always O(log n); next open location always known 2 4 5 7 6 10 8 11 9 12 14 20 Binary Heap Priority Q Data Structure How do we find the minimum?
2 4 5 7 6 10 8 11 9 12 14 20 Nifty Storage Trick 1 • Calculations: • child: • parent: • root: • next free: 2 3 4 7 5 6 8 9 12 10 11 0 1 2 3 4 5 6 7 8 9 10 11 12 12 2 4 5 7 6 10 8 11 9 12 14 20
2 4 5 7 6 10 8 11 9 12 14 20 Nifty Storage Trick 1 • Calculations: • child: left = 2*node right=2*node+1 • parent: floor(node/2) • root: 1 • next free: length+1 2 3 4 7 5 6 8 9 12 10 11 0 1 2 3 4 5 6 7 8 9 10 11 12 12 2 4 5 7 6 10 8 11 9 12 14 20
2 4 5 7 6 10 8 11 9 12 14 20 findMin pqueue.findMin() 2 Time = O(1)
2 4 5 7 6 10 8 11 9 12 14 20 DeleteMin pqueue.deleteMin() 2 20 4 5 7 6 10 8 11 9 12 14 20
Percolate Down 20 4 4 5 20 5 7 6 10 8 7 6 10 8 11 9 12 14 11 9 12 14 4 4 6 5 6 5 7 20 10 8 7 12 10 8 11 9 12 14 11 9 20 14
DeleteMin Code percolateDown(int hole) { tmp=A[hole]; while (2*hole <= size) { left = 2*hole; right = left + 1; if (right <= size && A[right] < A[left]) target = right; else target = left; if (A[target] < tmp) { A[hole] = A[target]; hole = target; } else break; } A[hole] = tmp; } Comparable deleteMin(){ x = A[1]; A[1]=A[size--]; percolateDown(1); return x; } Trick to avoid repeatedly copying the value at A[1] Move down Time = O(log n)(why ?)
2 4 5 7 6 10 8 11 9 12 14 20 Insert pqueue.insert(3) 2 4 5 7 6 10 8 11 9 12 14 20 3
Percolate Up 2 2 4 5 4 5 7 6 10 8 7 6 3 8 11 9 12 14 20 3 11 9 12 14 20 10 2 4 3 7 6 5 8 11 9 12 14 20 10
Insert Code void insert(Comparable x) { // Efficiency hack: we won’t actually put x // into the heap until we’ve located the position // it goes in. This avoids having to copy it // repeatedly during the percolate up. int hole = ++size; // Percolate up for( ; hole>1 && x < A[hole/2] ; hole = hole/2) A[hole] = A[hole/2]; A[hole] = x; } Time = O(log n)(why ?)
Performance of Binary Heap • In practice: binary heaps much simpler to code, lower constant factor overhead
Changing Priorities • In many applications the priority of an object in a priority queue may change over time • if a job has been sitting in the printer queue for a long time increase its priority • unix “renice” • Must have some (separate) way of find the position in the queue of the object to change (e.g. a hash table)
Other Priority Queue Operations • decreaseKey • Given the position of an object in the queue, increase its priority (lower its key). Fix heap property by: • increaseKey • given the position of an an object in the queue, decrease its priority (increase its key). Fix heap property by: • remove • given the position of an an object in the queue, remove it. Do increaseKey to infinity then …
BuildHeap • Task: Given a set of n keys, build a heap all at once • Approach 1: Repeatedly perform Insert(key) • Complexity:
BuildHeapFloyd’s Method 12 5 11 3 10 6 9 4 8 1 7 2 pretend it’s a heap and fix the heap-order property! 12 buildHeap(){ for (i=size/2; i>0; i--) percolateDown(i); } 5 11 3 10 6 9 4 8 1 7 2
Build(this)Heap 12 12 5 11 5 11 3 10 2 9 3 1 2 9 4 8 1 7 6 4 8 10 7 6 12 12 5 2 1 2 3 1 6 9 3 5 6 9 4 8 10 7 11 4 8 10 7 11
Finally… 1 3 2 4 5 6 9 12 8 10 7 11
Complexity of Build Heap • Note: size of a perfect binary tree doubles (+1) with each additional layer • At most n/4 percolate down 1 levelat most n/8 percolate down 2 levelsat most n/16 percolate down 3 levels… O(n)
Thinking about Heaps • Observations • finding a child/parent index is a multiply/divide by two • operations jump widely through the heap • each operation looks at only two new nodes • inserts are at least as common as deleteMins • Realities • division and multiplication by powers of two are fast • looking at one new piece of data terrible in a cache line • with huge data sets, disk accesses dominate
Solution: d-Heaps 1 • Each node has d children • Still representable by array • Good choices for d: • optimize performance based on # of inserts/removes • choose a power of two for efficiency • fit one set of children in a cache line • fit one set of children on a memory page/disk block 3 7 2 4 8 5 12 11 10 6 9 12 1 3 7 2 4 8 5 12 11 10 6 9
New Operation: Merge Merge(H1,H2): Merge two heaps H1 and H2 of size O(N). • E.g. Combine queues from two different sources to run on one CPU. • Can do O(N) Insert operations: O(N log N) time • Better: Copy H2 at the end of H1 (assuming array implementation) and use Floyd’s Method for BuildHeap. Running Time: O(N) Can we do even better? (i.e. Merge in O(log N) time?)
Binomial Queues insert : heap value heap findMin : heap value deleteMin : heap heap merge : heap heap heap • All in O(log n) time • Recursive Definition of Binomial Tree Bk of height k: • B0 = single root node • Bk = Attach Bk-1 to root of another Bk-1 • Idea: a binomial heap H is a forest of binomial trees: H = B0 B1 B2 ... Bkwhere each Bi may be present, or may be empty
Building a Binomial Tree • To construct a binomial tree Bk of height k: • Take the binomial tree Bk-1 of height k-1 • Place another copy of Bk-1one level below the first • Attach the root nodes • Binomial tree of height k has exactly 2k nodes (by induction) B0 B1 B2 B3
Building a Binomial Tree • To construct a binomial tree Bk of height k: • Take the binomial tree Bk-1 of height k-1 • Place another copy of Bk-1one level below the first • Attach the root nodes • Binomial tree of height k has exactly 2k nodes (by induction) B0 B1 B2 B3
Building a Binomial Tree • To construct a binomial tree Bk of height k: • Take the binomial tree Bk-1 of height k-1 • Place another copy of Bk-1one level below the first • Attach the root nodes • Binomial tree of height k has exactly 2k nodes (by induction) B0 B1 B2 B3
Building a Binomial Tree • To construct a binomial tree Bk of height k: • Take the binomial tree Bk-1 of height k-1 • Place another copy of Bk-1one level below the first • Attach the root nodes • Binomial tree of height k has exactly 2k nodes (by induction) B0 B1 B2 B3
Building a Binomial Tree • To construct a binomial tree Bk of height k: • Take the binomial tree Bk-1 of height k-1 • Place another copy of Bk-1one level below the first • Attach the root nodes • Binomial tree of height k has exactly 2k nodes (by induction) B0 B1 B2 B3
Building a Binomial Tree • To construct a binomial tree Bk of height k: • Take the binomial tree Bk-1 of height k-1 • Place another copy of Bk-1one level below the first • Attach the root nodes • Binomial tree of height k has exactly 2k nodes (by induction) B0 B1 B2 B3
Building a Binomial Tree • To construct a binomial tree Bk of height k: • Take the binomial tree Bk-1 of height k-1 • Place another copy of Bk-1one level below the first • Attach the root nodes • Binomial tree of height k has exactly 2k nodes (by induction) B0 B1 B2 B3 Recall: a binomial heap may have any subset of these trees
Why Binomial? • Why are these trees called binomial? • Hint: how many nodes at depth d? B0 B1 B2 B3
Why Binomial? • Why are these trees called binomial? • Hint: how many nodes at depth d? Number of nodes at different depths d for Bk = [1], [1 1], [1 2 1], [1 3 3 1], … Binomial coefficients of (a + b)k : k!/((k-d)!d!) B0 B1 B2 B3
Binomial Queue Properties Suppose you are given a binomial queue of N nodes • There is a unique set of binomial trees for N nodes • What is the maximum number of trees that can be in an N-node queue? • 1 node 1 tree B0; 2 nodes 1 tree B1; 3 nodes 2 trees B0 and B1; 7 nodes 3 trees B0, B1 and B2 … • Trees B0, B1, …, Bk can store up to 20 + 21 + … + 2k = 2k+1 – 1 nodes = N. • Maximum is when all trees are used. So, solve for (k+1). • Number of trees is log(N+1) = O(log N)
Definition of Binomial Queues Binomial Queue = “forest” of heap-ordered binomial trees B0 B2 B0 B1 B3 -1 1 21 5 3 3 2 7 1 9 6 11 5 8 7 Binomial queue H1 5 elements = 101 base 2 B2 B0 Binomial queue H2 11 elements = 1011 base 2 B3B1 B0 6
findMin() • In each Bi, the minimum key is at the root • So scan sequentially B1, B2, ..., Bk, compute the smallest of their keys: • Time: O(log n) (why ?) B0 B1 B2 B3
Binomial Queues: Merge • Main Idea: Merge two binomial queues by merging individual binomial trees • Since Bk+1 is just two Bk’s attached together, merging trees is easy • Steps for creating new queue by merging: • Start with Bk for smallest k in either queue. • If only one Bk, add Bk to new queue and go to next k. • Merge two Bk’s to get new Bk+1by making larger root the child of smaller root. Go to step 2 with k = k + 1.
Example: Binomial Queue Merge H1: H2: -1 5 1 3 21 3 9 2 7 6 1 11 5 7 8 6
Example: Binomial Queue Merge H1: H2: -1 5 1 3 3 9 2 7 6 1 21 11 5 7 8 6
Example: Binomial Queue Merge H1: H2: -1 5 1 3 9 2 7 6 1 3 11 5 7 8 21 6
Example: Binomial Queue Merge H1: H2: -1 1 3 5 2 7 1 3 11 9 5 6 8 21 6 7
Example: Binomial Queue Merge H1: H2: -1 1 3 2 1 5 7 11 3 5 8 9 6 6 21 7
Example: Binomial Queue Merge H1: H2: -1 1 3 2 1 5 7 11 3 5 8 9 6 6 21 7
Binomial Queues: Merge and Insert • What is the run time for Merge of two O(N) queues? • How would you insert a new item into the queue?