Memra

Amortized analysis

◈ 5 cards

Worst-case-average over a sequence (not probability); aggregate / accounting / potential; the dynamic-table doubling result.

Averaging cost over a sequence — with no probability

Amortized analysis bounds the average cost per operation over a worst-case sequence of operations. It shows that even if one operation is occasionally expensive, the average over the whole sequence is small. The critical distinction the exam tests:

> Amortized analysis involves no probability and no distribution. It is a worst-case guarantee on the average cost per operation — not an average-case (expected) analysis.

If any sequence of operations costs at most , the amortized cost per operation is , and that holds for every sequence, not just typical ones.

The three methods

  1. Aggregate — bound the total cost of the whole sequence directly, then charge to every operation equally.
  2. Accounting — assign each operation a (possibly different) amortized charge ; overcharges bank credit on data-structure objects, undercharges spend it. Valid as long as total credit stays , i.e. .
  3. Potential — define a potential on the data-structure state; the amortized cost is . By telescoping, , so if the amortized total upper-bounds the actual total.

All three give upper bounds on the same real cost; they only differ in bookkeeping. Pick whichever is most natural.

Warm-ups: the stack with MULTIPOP and the binary counter

MULTIPOP(S, k) pops items — a single call is , so a naive bound on operations is . But aggregate analysis nails it: each object is pushed at most once and popped at most once, so across the whole sequence there are at most pops total. Total cost , amortized . The accounting view: charge $\$2$ at each PUSH ($\$1$ to push now, $\$1$ of credit on the object for its eventual pop); then POP and MULTIPOP are $\$0$ amortized. The potential view: $\Phi = $ stack size — PUSH is $1 + 1 = 2$, MULTIPOP of $k'$ items is $k' - k' = 0$.

The -bit binary counter: INCREMENT flips every time, every other time, every fourth time, … So total flips over increments . Amortized per INCREMENT.

The headline result: dynamic-table doubling

A dynamic table (Python list, Java ArrayList, C++ vector) grows by doubling when it fills. A TABLE-INSERT that triggers a resize costs (copy everything to a bigger array); a non-resizing insert costs . Naive bound: . But resizes happen at sizes , so the total copy cost over inserts is (a geometric series). Total work , so insertion is amortized despite occasional resizes. (Contraction needs care: halving at rather than avoids thrashing, where alternating insert/delete triggers a resize every step.)

Worked example — count the copies, see the geometric series

Do appends into a table that starts at capacity 1 and doubles when full. The capacity passes through , and each doubling copies the existing elements: total copies for 16 appends. That is copies per append — less than one copy each on average, even though the single resize from 8 to 16 alone copied 8 elements. The expensive resizes are exactly cancelled by the cheap inserts between them: amortized, demonstrated, not just asserted.

methodthe bookkeepingstack with MULTIPOPaggregatebound total T(n), chargeT(n)/n≤ 2n ops ⇒ 2 eachaccountingbank credit on objectsPUSH $2, POP $0potentialĉ = c + ΔΦΦ = |S|: 2, 0, 0All three are upper bounds on the same actual cost.
Three bookkeeping schemes over one real cost. Each proves the stack with MULTIPOP is O(1) amortized, and none of them mentions a probability distribution — pick whichever is easiest for the structure at hand.
123456789101112cost123151119111total 27 ⇒ 2.25 per appendCopy work 1+2+4+8 = 15 — a geometric series, so O(n).
The first 12 of the 16 appends. Cost spikes exactly where the capacity doubles (1→2→4→8→16), copying 1, 2, 4 then 8 elements; every other append costs 1. The spikes are rare enough, and grow slowly enough, that the running average stays under a constant — that is what amortized O(1) means.
NORMAL ~/memra/learn/comp-372/amortized-analysis utf-8 LF