Amortized Analysis
Chapter 17
CPTR 430 Algorithms Amortized Analysis
Amortized Analysis Chapter 17 1 CPTR 430 Algorithms Amortized - - PowerPoint PPT Presentation
Amortized Analysis Chapter 17 1 CPTR 430 Algorithms Amortized Analysis Amortized Analysis Amortized analysis averages the time required to perform a sequence of operations on a data structure over all the operations performed An
CPTR 430 Algorithms Amortized Analysis
■ Amortized analysis averages the time required to perform a sequence
■ An individual operation may itself be relatively expensive, but its
■ Common types of amortized analysis: ❚ Aggregate analysis ❚ Accounting method ❚ Potential method
CPTR 430 Algorithms Amortized Analysis
■ Augmented stack ■ Binary counter
CPTR 430 Algorithms Amortized Analysis
■ push(x)—pushes element x onto the stack, as usual ■ pop()—pops the top element off of the stack and returns the popped
■ multiPop(k) pops the top k elements off of the stack ❚ Returns true if k elements could be popped ❚ Returns false if fewer than k elements were popped because the
CPTR 430 Algorithms Amortized Analysis
public class Stack { private Object[] stack; // Array of elements private int top; // Next available position public Stack(int capacity) { stack = new Object[capacity]; top = 0; // Stack is initially empty } public boolean isEmpty() { return top == 0; } public int size() { return top; } public void push(Object newElement) { if ( top < stack.length ) { stack[top++] = newElement; } } public Object pop() { Object result = null; if ( top > 0 ) { result = stack[--top]; } return result; } public boolean multiPop(int k) { while ( !isEmpty() && k != 0 ) { pop(); k--; } return k == 0; // k elements successfully popped off? } } CPTR 430 Algorithms Amortized Analysis
■ push(x)—O
■ pop()—O
■ MultiPop(k)—min
✂■ Consider a sequence of n stack operations on an initially empty stack ❚ The worst-case cost of a multiPop() is O
❚ The worst-case time for any stack operation is thus O
❚ A sequence on n stack operations, worst-case, would be O
■ This bound is correct but not tight
CPTR 430 Algorithms Amortized Analysis
■ Uses a fixed number of bits, k ■ The bits are stored in an array with length k ■ Lowest order bit is at index 0, so the counter’s value = k
i
✁■ Counts upward from 0 to k
✝■ Flipping a bit counts as work ■ More work occurs when carries must be done ■ Incrementing the maximum representable value k bits
✞ ✟✠ ✡k bits
✞ ✟ ✠ ✡CPTR 430 Algorithms Amortized Analysis
public class BinaryCounter { private int[] bitString; public BinaryCounter(int bits) { // Java automatically initializes the contents to zero bitString = new int[bits]; } public String toString() { String result = ""; for ( int i = bitString.length - 1; i >= 0; i-- ) { result += bitString[i]; } return result; } public void increment() { int i = 0; while ( i < bitString.length && bitString[i] == 1 ) { bitString[i] = 0; i++; } if ( i < bitString.length ) { bitString[i] = 1; } } } CPTR 430 Algorithms Amortized Analysis
■ A single execution of the increment() methods takes worst-case time
■ Thus a sequence of n increments on a counter object that is initially
■ This bound is correct, but not tight
CPTR 430 Algorithms Amortized Analysis
■ In aggregate analysis, we show that for all n, a sequence of n operations
■ The worst case amortized cost (or average cost) is thus T
■ This amortized cost is then applied to each operation even though
CPTR 430 Algorithms Amortized Analysis
■ Aggregate analysis can give a tighter upper bound for the sequence of
■ A single multiPop() operation can be expensive, but any sequence
■ Each item can be popped off at most once for each time it is pushed
■ The number of push() operations is at most n, so any sequence of n
CPTR 430 Algorithms Amortized Analysis
■ The number of push() operations is at most n, so any sequence of n
■ The average cost of an operation: O
■ Aggregate analysis assigns the amortized cost of each operation to be
■ The amortized cost of all three stack operations (even multiPop()) is
CPTR 430 Algorithms Amortized Analysis
■ Notice that not all bits flip every time increment() is called ❚ bitString[0] flips every time
❚ bitString[1] flips every other time
❚ bitString[2] flips every fourth time
■ For i
■ For i
✂CPTR 430 Algorithms Amortized Analysis
i
✁∞
i
✁CPTR 430 Algorithms Amortized Analysis
CPTR 430 Algorithms Amortized Analysis
■ The
■ Some operations may be charged more or less than they actually cost ■ The amount charged to an operation is its amortized cost ■ Operations charged more than their actual cost build credit stored
■ This credit can be used to help pay for operations that are charged less
■ Note that this approach is different from aggregate analysis in which all
CPTR 430 Algorithms Amortized Analysis
■ We want the worst case analysis to show that the amortized (average)
■ We must show that the total amortized cost of a sequence of operations
❚ This relationship must hold for all sequences ❚ Therefore, the applied credit can never be negative ❚ Should the credit be allowed to become negative, then the cost of the
CPTR 430 Algorithms Amortized Analysis
■ Let ci be the actual cost of operation i ■ Let
■ The constraint that the amortized cost be an upper bound on the actual
n
i
✁1
n
i
✁1
■ The total credit is the difference between the amortized cost and the
n
i
✁1
n
i
✁1
CPTR 430 Algorithms Amortized Analysis
CPTR 430 Algorithms Amortized Analysis
■ Every push() operation is not only charged its actual cost (1), but an additional cost
■ This credit is associated with the object pushed onto the stack ■ The operations pop() and multiPop() need be charged nothing, as their cost has
■ When an object is popped off, the credit associated with that object pays for the pop
■ Thus for any sequence of n push(), pop(), and multiPop() operations, the total
■ The total amortized cost is O
✄CPTR 430 Algorithms Amortized Analysis
■ The running time of increment() is proportional to the number of bits
■ Thus, the cost to flip a bit is 1 ■ Let the amortized cost to flip a bit from 0 to 1 be 2: ❚ 1 to flip the bit to 1, plus ❚ 1 credit, stored with that bit, to flip the bit back to 0 ■ Let the amortized cost to flip a bit from 1 to 0 be 0: ❚ Cash in on the stored credit of 1 when it was previously made a 1
CPTR 430 Algorithms Amortized Analysis
CPTR 430 Algorithms Amortized Analysis
■ The accounting method represents prepaid work as credit associated
■ The potential method represents the prepaid work as “potential energy”
■ This potential energy (or just potential) is not associated with any
■ This potential can be used to pay for future operations
CPTR 430 Algorithms Amortized Analysis
■ D0—the intial data structure upon which n operations are to be
■ ci—the actual cost of the ith operation, 1
■ Di—the data structure that results after applying the ith operation to
■ Φ—the potential function that maps each data structure Di to a real
■
CPTR 430 Algorithms Amortized Analysis
n
i
✁1
i
✁1
i
✁1
i
✁1
i
✁1
CPTR 430 Algorithms Amortized Analysis
n
i
✁1
i
✁1
■ Φ
i
✁1
n
i
✁1
■ Since we may not know in advance exactly how many operations will
❚ This says we “pay in advance” ❚ This ensures that the amortized cost is always an upper bound ■ Usually, Φ
■ Our task is then to show that
CPTR 430 Algorithms Amortized Analysis
■ Φ
❚ the amortized cost
■ Φ
❚ the amortized cost
CPTR 430 Algorithms Amortized Analysis
■ Let Φ be the number of objects on the stack ■ For an empty stack, Φ
CPTR 430 Algorithms Amortized Analysis
■ Let the ith operation on a stack containing s objects be a push() ■ The potential difference is
■ Given our formula for amortized cost, we get
CPTR 430 Algorithms Amortized Analysis
■ Let the ith operation on a stack containing s objects be a pop() ■ ci, the actual cost of the operation, is 1 ■ The potential difference is
■ Given our formula for amortized cost, we get
Amortized Analysis
■ Let the ith operation on a stack containing s objects be a multiPop(k) ■ k
■ ci, the actual cost of the operation, is k
Amortized Analysis
■ The amortized cost of each of the operations is O
■ The total amortized cost for a sequence of n operations is thus O
■ We showed that the amortized cost of n operations is an upper bound
■ Therefore, the worst-case cost of n operations is O
CPTR 430 Algorithms Amortized Analysis
■ Define the potential of the counter after the ith increment to be bi, the
❚ Φ
❚ Φ
❚ Φ
■ Suppose the ith increment resets ti bits ■ ci, the actual cost, is at most ti
■ bi
■ bi
✂CPTR 430 Algorithms Amortized Analysis
CPTR 430 Algorithms Amortized Analysis
■ For a counter starting at 0, Φ
■ The worst case cost of n increment() operations is thus O
CPTR 430 Algorithms Amortized Analysis
CPTR 430 Algorithms Amortized Analysis
■ In programming
CPTR 430 Algorithms Amortized Analysis
■ In many applications the maximum needed size may not be known
■ Erring on the side of safety (allocating an incredibly large array, just in
■ The conservative approach (allocating the minimum required for the
❚ A new array must be created of the needed size ❚ All the elements in the existing array must be copied over into the
❚ This activity is necessary since array elements must occupy
CPTR 430 Algorithms Amortized Analysis
■ Amortized analysis can be used to show that the cost of insertion into a
■ Amortized analysis can also be used to show that the unused space in
CPTR 430 Algorithms Amortized Analysis
■ For a non-empty array T, the load factor, α
■ A full array has a load factor of 1 ■ An empty array (allocated size
■ If the load factor of a dynamic array is bounded below by a constant,
CPTR 430 Algorithms Amortized Analysis
■ To insert an item into a full array, the array must be expanded ■ A common strategy: make the new array twice as big as the filled array ❚ This ensures the load factor will always be at least 1
❚ The amount of unused space never exceeds 1
CPTR 430 Algorithms Amortized Analysis
public class DynamicArray { private Object[] array; private int numberOfElements; // Number of elements public DynamicArray() { this(0); // Zero-size array } public DynamicArray(int initialCapacity) { array = new Object[initialCapacity]; numberOfElements = 0; } public Object get(int pos) { if ( pos < numberOfElements && pos >= 0 ) { return array[pos]; } return null; } public void insert(Object newElement) { // Details on next slide . . . } }
CPTR 430 Algorithms Amortized Analysis
CPTR 430 Algorithms Amortized Analysis
■ The code within insert():
■ Notice that this simply a number of elementary insertions ■ If an insertion causes an array expansion, then the cost of the insertion
CPTR 430 Algorithms Amortized Analysis
■ Assumption: The time to allocate a new array is dominated by the cost
■ ci is the cost of the ith insertion ■ If there is room in the current array, ci
■ If the array is full, then ci
❚ 1, for the elementary insertion of the new element, plus ❚ i
✝CPTR 430 Algorithms Amortized Analysis
■ If n insertions are performed, the worst case cost of a single insertion
■ For n insertions then, the total running time is bounded by O
■ As in our earlier analyses, this bound is correct but not tight ❚ The cost of expanding the array is not incurred often ❚ The ith insertion causes an expansion only when i
✝■ What, then, is the amortized cost for insert()?
CPTR 430 Algorithms Amortized Analysis
n
i
✁1
j
✁CPTR 430 Algorithms Amortized Analysis
■ Aggregate analysis showed each operation had a cost of 3 ■ In the accounting method we will charge 3 for each insertion: ❚ The insertion of the element itself costs 1 ❚ A credit of 1 is associated with this element to cover its own move
❚ Another credit of 1 is associated with this element to cover the move
CPTR 430 Algorithms Amortized Analysis
■ The number of elements in the array is thus m
■ The array contains no credit ■ Charge a cost of 3 for each insertion: ❚ 1 for inserting the new element ❚ 1 as credit to move this element in the future ❚ 1 as credit to move one of the m
■ The array will become full with m elements after m
■ When full, the total credit is 2
✄■ The expansion will consume all the credit, again leaving a new array twice as large
CPTR 430 Algorithms Amortized Analysis
■ Keying on our accounting method analysis, define a potential function
❚ Φ is 0 immediately after an expansion ❚ Φ increases as elements are inserted ❚ Φ is equal to the array size by the time the array is full ■ For dynamic array A, let ❚ num
❚ size
CPTR 430 Algorithms Amortized Analysis
■ From the previous slide
■ Immediately after an expansion
■ The table is always at least half full, so
CPTR 430 Algorithms Amortized Analysis
CPTR 430 Algorithms Amortized Analysis
■ Let ❚ numi be the number of elements in the array after the ith insertion ❚ sizei be the size of the array after the ith insertion ❚ Φi be the potential after the ith insertion ■ Initially ❚ num0
❚ The ith insertion does not trigger an expansion ❚ The ith insertion does trigger an expansion
CPTR 430 Algorithms Amortized Analysis
■ sizei
■ Amortized cost
CPTR 430 Algorithms Amortized Analysis
■ sizei
■ sizei
■ Amortized cost
CPTR 430 Algorithms Amortized Analysis
CPTR 430 Algorithms Amortized Analysis