Binary counter (amortized analysis)
Increment a binary counter eight times; one increment can flip many bits, but the average is below 2.
We have a binary counter of k bits and increment it many times. An increment clears the trailing 1 bits (the
carry) and sets the first 0. In the worst case one increment flips all k bits. So do n increments cost up to
n·k flips?
- Time:
O(k) for one increment of k bits, O(1) amortized - Space:
O(1) - CLRS, section 16.1
From 0 to 8: 15 bit flips for 8 increments in all, under 2 per increment.
def binary_counter(bits):flips = 0for n in range(1, 9):i = 0while i < len(bits):if bits[i] == 0:breakbits[i] = 0flips = flips + 1i = i + 1if i < len(bits):bits[i] = 1flips = flips + 1return flips
Start
Local variables
Orange = changed in this step
bits list
Call stack
- binary_counter()line 1
Explanation
The problem
We have a binary counter of k bits and increment it many times. An increment clears the trailing 1 bits (the
carry) and sets the first 0. In the worst case one increment flips all k bits. So do n increments cost up to
n·k flips?
Amortized analysis
No. Bit 0 flips on every increment, bit 1 on every second one, bit 2 on every fourth, and so on. In total:
n + n/2 + n/4 + … < 2n
The amortized cost of an increment is below 2, even though some increments are expensive. This is the key idea of amortized analysis: the total cost of a sequence of operations, not the worst cost of one.
What to watch in the trace
- Bit 0 (the lowest) is on the left of the picture.
- Use the "every loop round" detail level to go one increment at a time, and compare the number of
resetandsetsteps with 2 × 8 = 16.