### Amortization Analysis using the Banker's model

• Worst case cost and average cost

• Cost of owning a car:

 Right now, you have a car A car will last 10 years           It cost \$20,000

• \$60,000 question:

 How much does it cost to own a car ???          (

• Approach 1: the worst case cost

 Use the current car for 10 years Then paid \$20,000 to buy another car

• Approach 2: the average cost

 Use the current car for the next 10 years Every year, put (pay) \$2,000 in the bank After 10 year, use the money to buy a car....

• Example amortization (average) analysis: doubling array stacks

• Stack implemented using an array:

 ``` public void push(E obj) { /* ------------------------------- Check if stack is full ------------------------------- */ if ( t == S.length() - 1 ) { /* ----------------------------------- Stack full: double the stack space ------------------------------------ */ A = (E[]) new Object[S.length() * 2]; // 2 x space for ( i = 0; i <= S.length() - 1; i++ ) A[i] = S[i]; // Copy old array over S = A; // Set new array } /* --------------------------- The actual push operation --------------------------- */ ++t; // Next element S[t] = obj; // Store it } ```

• Question:

 What is the cost (in terms of the number of copy operations) of a push operation when the stack contains n items ?

• Worst case cost of a push() operation:

• A push operation may cause the array size to double if n == S.length()

• If this happens, there will be n copy operations to re-populate the new stack

• And 1 copy operation to save the new item

• Worst case cost of a (one) push operation:

 n+1 copy operations

(However, the worst case happens rarely !!!)

• Average cost of a push() operation:

• Consider k consecutive push operations:

 ``` Initial array size = 1 |_| push(1) |1| 1 push(2) |1| |1|_| 1 Double array |1|2| 1 push(3) |1|2| |1|2|_|_| 2 Double array |1|2|3|_| 1 push(4) |1|2|3|4| push(5) |1|2|3|4| |1|2|3|4|_|_|_|_| 4 Double array |1|2|3|4|5|_|_|_| 1 push(5) |1|2|3|4|5|6|_|_| 1 And so on... ```

• The number of copy operation incurred in k consecutive push operations:

 ``` item: 1 2 3 4 5 6 7 8 9 10 # copy for k push ops = 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + .... + 1 + 2 + 4 + 8 ... = k + 1 + 2 + 4 + ... + lg(k) ≤ k + 1 + 2 + 4 + ... + k Let: S = 1 + 2 + 4 + .... + k 2×S = 2 + 4 + .... + k + 2×k - ---------------------------------------------- -S = 1 - 2×k Or: S = 2×k - 1 Therefore: # copy for k push ops ≤ k + 2×k - 1 ≤ 3×k ```

• Average number of copy operations incurred in one push operation:

 ``` 3×k Avg. # copy operation per push op ≤ ------ k ≤ 3 !!! ```

Conclusion:

 Average cost (running time) of a push() operation = O(1) !!!

• Banker's model of amortization analysis

• The banker's model is piecemeal approach to perform a amortization analysis of an operation

• Illustration using the push() operation:

• Most push() operation cost 1 copy operation

But some push operations cost much more than 1 copy operation

• We amortize the cost of the more expensive push operation onto every push operation as follows:

 "Pay" the 1 copy operation cost for the ordinary push operation "Tag on" 2 more copy operation cost for each push operation to "pay" for the more expensive push operation when it happens Total cost for each push() operation = 3 copy operations

• Claim:

 When we count the cost of a push() operation as 3 copy operations, we will always have enough saved copy operation to perform the more expensive (but rare) push operations that require array doubling

• Example:

• Initial stack:

• push(4): cost = \$3 (= 3 copy operations)

1 copy operation used to perform the push(4)
2 copy operations saved

• push(7): cost = \$3 (= 3 copy operations)

Use 1 saved copy operation to perform array doubling

1 copy operation used to perform the push(7)
2 copy operations saved

• push(2): cost = \$3 (= 3 copy operations)

Use 2 saved copy operation to perform array doubling

1 copy operation used to perform the push(2)
2 copy operations saved

• push(9): cost = \$3 (= 3 copy operations)

1 copy operation used to perform the push(2)
2 copy operations saved

• push(6): cost = \$3 (= 3 copy operations)

Use 4 saved copy operation to perform array doubling

1 copy operation used to perform the push(6)
2 copy operations saved

• After 3 more push() operations:

Note:

 By the time that we need to perform array doubling, the # push() operations has saved enough copy operations for the array doubling !!!

• True claim:

 When we count the cost of a push() operation as 3 copy operations, we will always have enough saved copy operation to perform the more expensive (but rare) push operations that require array doubling

Conclussion:

 The average (amortized) cost of 1 (one) push operation ≤ 3

• Requirement for a correct amortization performance analysis

• The amortization analysis on the run time performance is correct (sound) if:

 The total # saved (credit) operations in the system must always be ≥ 0

• When this property does not hold, there may be situations where the push() operation cannot be performed

We have then under-estimated the average run time requirement !!!