We will master the three methods of amortized analysis: 1. Aggregate Method (Global brute-force counting) 2. Accounting Method (Credit/Debit system) 3. Potential Method (Physicist’s energy model)
Applied to two classic problems: * Multipop Stack (Amortized O(1) operations) * Dynamic Tables (Amortized O(1) insertions)
Standard Stack augmented with a third operation:
PUSH(x): push x onto stack — actual cost 1POP(): pop top element — actual cost 1MULTIPOP(k): pop up to k elements: c = \min(k, \text{stack size})A single MULTIPOP(n) operation could cost O(n) if the stack is full. * Does a sequence of n operations cost O(n^2)?
Key Insight: An element must be PUSHed onto the stack before it can be POPped.
Total Cost of n Operations: \text{Cost}_{\text{total}} = \text{Total PUSH cost} + \text{Total POP/MULTIPOP cost} \text{Cost}_{\text{total}} \le n + n = 2n
Amortized Cost per operation: \le 2n / n = O(1). ✓
We assign artificial amortized costs (charges) to operations:
PUSH(x): Charge 2 credits
POP() & MULTIPOP(k): Charge 0 credits
Credit Invariant: \text{Total Amortized Cost} - \text{Total Actual Cost} = \text{Credit Balance} = \text{Stack Size} \ge 0 Since balance is always non-negative, amortized cost bounds actual cost. Amortized cost = O(1) per operation. ✓
Define potential function: \Phi(D_i) = \text{size of stack}.
Amortized Cost Derivations (\hat{c}_i = c_i + \Phi(D_i) - \Phi(D_{i-1})):
PUSH: \hat{c}_i = 1 + (\text{size} + 1 - \text{size}) = 2POP: \hat{c}_i = 1 + (\text{size} - 1 - \text{size}) = 0MULTIPOP(k): (pops k' = \min(k, s) elements) \hat{c}_i = k' + (\text{size} - k' - \text{size}) = 0Amortized cost is O(1) per operation. ✓
Question for the Class
“What if we define our potential function as \Phi(D_i) = 2 \cdot \text{stack size}? Will the analysis still work? What will be the new amortized costs?”
Answer: Yes, it still works. * PUSH: \hat{c}_i = 1 + 2(1) = 3 * POP: \hat{c}_i = 1 + 2(-1) = -1 \le 0 * MULTIPOP(k): \hat{c}_i = k' + 2(-k') = -k' \le 0 Amortized bounds are still O(1) per operation!
Problem: We need an array that dynamically resizes to accommodate insertions. * Start with size 1. * When table is full and we insert, we double its size and copy all elements to the new memory block.
Let’s trace the actual cost of the first 16 insertions:
| i | size before | copy cost | insert cost | actual cost | cumulative cost |
|---|---|---|---|---|---|
| 1 | 1 | 0 | 1 | 1 | 1 |
| 2 | 1 (full) | 1 | 1 | 2 | 3 |
| 3 | 2 | 0 | 1 | 1 | 4 |
| 4 | 2 (full) | 2 | 1 | 3 | 7 |
| 5–7 | 4 | 0 | 1 each | 1 each | 10 |
| 8 | 4 (full) | 4 | 1 | 5 | 15 |
| 9–15 | 8 | 0 | 1 each | 1 each | 22 |
| 16 | 8 (full) | 8 | 1 | 9 | 31 |
Notice that for n=16, total actual cost is 31 < 2n.
Generalizing the trace: Doubling occurs only when i - 1 is a power of 2.
Total Cost of n Insertions: T(n) = \sum_{i=1}^{n} c_i = n + \sum_{k=0}^{\lfloor \log_2(n-1) \rfloor} 2^k T(n) < n + 2 \cdot 2^{\lfloor \log_2(n-1) \rfloor} < n + 2n = 3n
Amortized Cost per Insertion: \hat{c} = \frac{T(n)}{n} < \frac{3n}{n} = 3 = O(1)
Accounting Scheme: Charge 3 credits per insertion. * 1 credit pays for the insertion itself. * 1 credit is stored on the element to pay for its future copy. * 1 credit is stored to pay for copying an older element.
Why does this cover all copying? Between size m (just doubled) and 2m (full): * We perform m insertions. * The last m/2 insertions generate m/2 \times 2 = m credits. * When table becomes full, we have exactly m credits in the pool. * This pays for copying all m elements during the next doubling.
Define potential function: \Phi(D_i) = 2 \cdot \text{num}_i - \text{size}_i
Amortized Cost (\hat{c}_i = c_i + \Delta\Phi):
Amortized cost is 3 = O(1) per insertion. ✓
Question for the Class
“Why is charging 2 credits per insertion insufficient? Show at which step the credit invariant fails.”
Answer: Right before doubling from size m to 2m, we have done m/2 new insertions. * If we charged 2 credits (1 for insert, 1 saved), we would only have m/2 credits in the pool. * But copying m elements requires m credits. The invariant fails and the pool goes negative.
| Data Structure | Operation | Worst-Case Cost | Amortized Cost |
|---|---|---|---|
| Binary Counter | INCREMENT | O(k) | O(1) |
| Multipop Stack | PUSH / POP / MULTIPOP | O(n) | O(1) |
| Dynamic Table | INSERT | O(n) | O(1) |
Important
Takeaway: Amortized analysis gives a realistic guarantee of performance over a sequence of operations, proving that rare expensive operations do not ruin global efficiency.
CS F364: Design & Analysis of AlgorithmsTulasimohan Molli