Professional Documents
Culture Documents
Fall 2014
Page 1
Fall 2014
DIY. INCREMENT updates HP. RESET changes bits 0,1,, HP to 0 and update HP to -1.
(b)
We charge US$2 whenever a bit is set (changes from 0 to 1). In addition, we also charge
SG$2 per INCREMENT operation -- SG$1 to check and update HP where necessary, and
SG$1 to stick to that bit to pay for a subsequent RESET operation. So, every bit 0,1,2,HP
has a SG$1 to pay for a future RESET operation.
Amortized Analysis:
Cost of INCREMENT operation:
Changing bits from 1 to 0 (line 3) is free. Changing bit from 0 to 1 cost US$2.
Cost of checking and updating HP is SG$1 (S$1 is saved up).
Amortized cost per INCREMENT operation: US$2 + SG$2. (constant time).
Cost of RESET operation:
Changing bits 0, 1, 2,, HP to 0 is free since each bit has SG$1 stuck to it.
Resetting HP to -1 is SG$1.
Amortized cost per RESET operation: SG$1.
(constant time).
Cost of any sequence of n INCREMENT/RESET operations from zero counter is O(n) time.
Page 2
Fall 2014
[NOTE: This solution sketch is INTENTIONALLY made more detailed for the
benefit of those who are seeing amortized complexity analysis for the first time.]
D1. Exercises 17.3-6 of [CLRS] (Queue with Two Stacks)
Show how to implement a queue with two ordinary stacks so that the amortized cost of
each ENQUEUE and each DEQUEUE operation is O(1).
SOLUTION SKETCH:
Idea: Queue is FIFO structure, but we are given stack, which is a LIFO structure.
We assume that we already have the Stack data structure with PUSH and POP operations.
To build our Queue Q, (wow! sounds like qq.com) we use two stacks Stk1 and Stk2.
So, we ENQUEUE items into Stk1 (they store in LIFO format, TOP of Stk1 is last-in item).
When we DEQUEUE from our Queue, if Stk2 is empty, then we need the bottom item of
Stk1. So, we POP off items from Stk1 and PUSH into Stk2, until Stk1 is empty.
Then the items in Stk2 are in FIFO format. And to DEQUEUE, we just POP from Stk2.
Thus, the general procedure for DEQUEUE is as follows: if Stk2 is not empty, then POP
from Stk2. Else if Stk1 is not empty, we move items from Stk1 into Stk2 (as described
above), then POP from Stk2. If Stk1 is also empty, we have a Queue underflow error.
Amortized Analysis: We assign to each ENQUEUE operation $3. $1 is used to pay PUSH
into Stk1, and the remaining $2 is stuck with the item (in Stk1), to pay for subsequent
POP from Stk1 and PUSH into Stk2. Each item in Stk1 has $2, while items in Stk2 has
no credit.
And we assign each DEQUEUE operation $1 to pay for POP from Stk2. Note that if the
deq operation needs to move items from Stk1 into Stk2, that is paid for by the credits in
the Stk1 items. So, amortized cost is $1.
D2. (Exercise 17.1-2 of [CLRS]) (INCREMENT and DECREMENT)
Show that if a DECREMENT operation were included in the k-bit counter example, n
operations could cost as much as (nk) time. (Note: Give such a sequence of operations.)
SOLUTION SKETCH:
Idea: This is similar to T5-R1. If we have INCREMENT and DECREMENT operations, then
we may have a situation where the worst-case time occurs very often and it is not
possible to amortize out the worst-case time.
Now, lets look at the specifics.
The worst-case of INCREMENT occurs when the binary counter is at (1111) and the
operation cost is k flips. (After this, the counter becomes (0000), which is very good
scenario for the INCREMENT operation.
The worst-case of DECREMENT occurs when the binary counter is at (0000) and the
operation cost is k flips. After that the counter becomes (1111).
Thus, if we have a sequence of n/2 {DECREMENT, INCREMENT} operations, then each
operation cost is k flips (worst-case time). So, the total cost of n operations is nk flips.
Hence, total for this sequence of operations is (nk) time.
Page 3
Fall 2014
D3. Modified from Problem 17.3-3 of [CLRS]) Amortized Analysis of Binary Heap
Consider the usual binary min-heap data structure (from [CLRS]-C6), with INSERT and
DELETEMIN done in O(log n) worst-case time. Give an amortized analysis that shows that
INSERT has amortized time O(log n) and DELETEMIN has amortized time O(1).
SOLUTION SKETCH: Intuitive Idea: We know that actual cost of DELETEMIN is O(h)
in the worst-case, where h is the height of the tree (more precisely, h = lg n). Actually, it
makes 2h comparisons when we do the HEAPIFY operation during DELETEMIN.
Now, how can we make its amortized cost O(1) for DELETEMIN?
So, there must be savings from somewhere else and the only other operation is INSERT,
so we should save credit for DELETEMIN when doing INSERT.
Next, how much to save?
In the worst-case, HEAPIFY traces a path of length h from the root down to some leaf, and
makes 2 comparisons per level down this path. So, it takes 2h credit at least.
But, when we INSERT that leaf node, it also requires a path of length h in the worst-case.
So, we can save up the 2h credits when we insert. So, each node on that path will save an
additional 2 credits, to be used later for DELETEMIN operation.
Amortized Analysis: Accounting method;
It is not hard to show (by mathematical induction, for example) that in each node x, the
amount of credits saved is 2*size(Tx), where size(Tx) is the number of nodes in Tx, the
subtree root at x. Another way you can show it is via a table (like that in L6-Slide-33), but
the entries are heaps of different sizes 1, 2, 3, .
Then, we assign a cost of $(3h) for each INSERT operation, where h is the height of the
heap after INSERT operation. $(h) is used up during the insertion process. Then we stick $2
to each node in the insert path (of length h) all the way to the root, giving a total of $(2h).
Then, we during the DELETEMIN operation, we have sufficient credit to pay for HEAPIFY
procedure. During DELETEMIN, when we decrease the size of the heap by 1, we also
remove $(2h) credit which is sufficient to pay for the HEAPIFY procedure.
(Work out the rest of the details yourself, if you still dont get it all.)
Page 4
Fall 2014
After an INSERT operation, if the table is more than fill, we allocate a new table
twice as big as current table, insert everything into the new table, and then free the
old table.
After a DELETE operation, if the table is less than full, we allocate a new table
half as big as our current table, insert everything into the new table, and then free
the old table.
Show that for any sequence of n operations (any combination of INSERT or DELETE
operations), the amortized time per operation is still a constant.
(Note: Do not use the potential method (it makes it much more difficult))
[* A little bit harder, but not too much harder. Can skip if there is not enough time.]
SOLUTION SKETCH:
First, make sure you understand how the INSERT and DELETE works for the dynamic table
covered in the lectures. (Read lecture notes L6-Slide-108-118 and [CLRS]-C17.4.2)
Intuitive Idea:
One simplification is to consider expansion-credits and contraction-credits separately.
Consider the situation before-and-after a table expansion. For good amortized costs, the
table should have $0 expansion-credit after table expansion. So, how to do that?
Let new table size after expansion be n.
Just after table expansion, the load-ratio = (#occupied)/(table-size), of the table is 3/8.
And the next table expansion will happen when the table gets to be 6/8 full.
So, each of the 3/8n new inserted items must save expansion-credits for itself-and-a-buddy.
So, for each INSERT operation, we add give $3 to be used as follows: $1 for insert the
item itself, $2 saved expansion-credits to move itself-and-a-buddy during expansion.
Now, consider the situation before-and-after a table contraction. For good amortized costs,
the table should have $0 contraction-credit after table contraction. So, how to do that?
Let new table size after contraction be n.
Just after table contraction, the load-ratio = (#occupied)/(table-size), of the table is 1/2.
The next table contraction happens when table becomes 1/4 full (after deleting n/4 items).
So, each of the n/4 deleted items must save contraction-credits for the n/4 remaining items.
So, for each DELETE operation, we add give $2 to be used as follows: $1 for delete the
item itself, $1 saved contraction-credit to move one-buddy during contraction.
Finally, you work out everything and make sure that we never run into a deficit.
(Note: The system will lose some credits. But, this shows O(1) time per operation. )
Page 5