WPI Worcester Polytechnic Institute

Computer Science Department
------------------------------------------

CS2223 Algorithms 
Homework 4 Solutions - B Term 2005

By David Toth  

------------------------------------------

  1. Yes, there is a greedy algorithm for the cashier problem that always produces the optimal solution.

    Part 1

    Step Cost Times Executed Total Cost
    // Get total change in cents from command line argument.      
    int change = Integer.parseInt(args[0]); C0 1 C0
    // Use Dollars Coins (100 cents) First      
    while (change >= 100) { C1 <= CEILING(change/100) <= C1*CEILING(change/100)
    Hand Customer Dollar Coin C2 <= CEILING(change/100) - 1 <= C2*[CEILING(change/100) - 1]
    change = change - 100 C3 CEILING(change/100) - 1 <= C3*[CEILING(change/100) - 1]
    }      
    // Use Quarters (25 cents) Next      
    while (change >= 25) { C4 <= 5 <= c4*5
    Hand Customer Quarter C5 <= 4 <= c5*4
    change = change - 25 C6 <= 4 <= c6*4
    }      
    // Use Dimes (10 cents) Next      
    while (change >= 10) { C7 <= 3 <= C7*3
    Hand Customer Dime C8 <= 2 <= C8*2
    change = change - 10 C9 <= 2 <= C9*2
    }      
    // Use Nickels (5 cents) Next      
    while (change >= 5) { C10 <= 2 <= C10*2
    Hand Customer Nickel C11 <= 1 <= C11*1
    change = change - 5 C12 <= 1 <= C12*1
    }      
    // Use Pennies (1 cent) Next      
    while (change >= 1) { C13 <= 6 <= C13*6
    Hand Customer Penny C14 <= 5 <= C14*5
    change = change - 1 C15 <= 5 <= C15*5
    }      

  2. Part 2

    (Note: For pedagogical reasons, the proof provided here is very detailed. We don't expect such a detailed proof in your homework solutions, but want to show you how the full, detailed proof goes.)

    We prove the algorithm always works by showing that the solution our greedy algorithm produces must be the same as the actual optimal solution. So we show that the number of dollars, quarters, dimes, nickels, and pennies that our greedy algorithm uses is the same as the number of each type of coin that the optimal solution would use.

    We first show the pennies used by our greedy solution and the optimal solution are the same. Our greedy algorithm only uses pennies when the amount of change left to be given is less than 5 cents, so our solution uses 0, 1, 2, 3, or pennies. Now the optimal solution can only use 0, 1, 2, 3, or pennies as well, because it would not be optimal if it used 5 pennies. To be optimal, every 5 pennies would have to be replaced by a nickel, because that would use fewer coins. Note the sum of the value of the coins that are not pennies is a multiple of 5 in both solutions, so the total of the other coins in both cases ends in a 0 or 5. Thus, the number of pennies used by both solutions must be the same, because if that was not the case, then the total amount of change would be different between the two solutions.

    Now we also know that the number of nickels in each solution must be 0 or 1, because the optimal solution would not have used two nickels instead of a dime (that would contradict optimal), and our greedy algorithm would not have either since it won't use nickels until there's less than 10 cents left to hand back.

    Note that for both solutions, 0 <= the number of quarters <=3 because otherwise, the greedy algorithm would have used a dollar in place of 4 quarters and the optimal one would have too (otherwise it wouldn't be optimal). In fact, for the greedy algorithm, 0 <= the number of dimes <= 2 and 0 <= the number of nickels <= 1 for both algorithms as well because if there were more than 2 dimes, the greedy algorithm would have used another quarter, and if there were more than 1 nickels, the greedy algorithm would have used another dime. These bounds hold for the optimal algoithm as well, because it would never have 2 nickels instead of a dime and it would never have 3 dimes instead of a quarter and a nickel, because that would contradict it being optimal. Thus, for both solutions, there are at most 6 coins other than pennies and dollars. We know the number of pennies are the same, so there are two cases:

    Case 1 - If the numbers of dollar coins for both solutions are the same, then both solutions have 6 or fewer coins that are dimes, nickels, and quarters and the sum of the values of those coins must be equal or else only 1 solution is correct (and we know our greedy solution is always correct if not optimal). If both solutions have the same coins, then both the greedy and optimal solutions use the same coins, so therefore, the greedy solution is optimal. If the amount of money from the coins is the same but the coins are different, then we need to show that any two sets of coins that add up to the same amount of money are such that the least number of coins would be chosen by both the optimal algorithm and the greedy algorithm. That will show that the greedy algorithm produces the optimal solution. So the sets of 6 or fewer coins are shown below, and the only cases where two sets of coins add up to the same amount of money are: n + d + d = 25, q = 25, q + q = 50, n + d + d + q = 50, n + d + d + q + q = 75, q + q + q = 75. In all of these cases, it is clear that the greedy algorithm would choose the fewer number of coins. It is also clear that the optimal solution would also contain the smaller number of coins by the definition of optimal. Thus, the greedy solution is the optimal one in this case.









    Case 2 - If the numbers of dollar coins for both solutions are different, then the greedy solution must have at least 1 more dollar coin than the optimal solution, so the optimal solution has at least $1 in change split between nickels, dimes, and quarters more than the greedy solution does. However, the optimal solution can't use more than 3 quarters, 2 dimes, and 1 nickel, which adds up to only 1 dollar. If the greedy solution has any nickels, dimes, or quarters, then the "optimal" solution can't be making change for the same amount of money, so the amounts of money can't be the same for the two solutions. This means that only one solution is correct, and since our greedy algorithm always produces a correct (if not also optimal solution), it would mean that no other optimal solution exists and therefore the greedy solution is optimal. If the greedy solution does not use any nickels, dimes, or quarters, then the "optimal" solution must be either for a different amount of money (which we explained makes our greedy solution optimal) or if it is for the same amount of money, then the optimal solution would not have included a dollar in change that is more coins than a single dollar coin because that would contradict it being optimal.

    Now, since the greedy and optimal algorithms always use the same number of coins, the greedy algorithm must be optimal.

    Part 3

    Total Cost <= C0 + C1*CEILING(change/100) + C2*[CEILING(change/100) - 1] + C3*[CEILING(change/100) - 1] + c4*5 + c5*4 + c6*4 + C7*3 + C8*2 + C9*2 + C10*2 + C11*1 + C12*1 + C13*6 + C14*5 + C15*5

    But C1*CEILING(change/100) + C2*[CEILING(change/100) - 1] + C3*[CEILING(change/100) - 1] is the only part of this that is a function of the size of the input instead of just the sum of some constants multiplied together, so C1*CEILING(change/100) + C2*[CEILING(change/100) - 1] + C3*[CEILING(change/100) - 1] is the highest order term.

    And we can see that [CEILING(change/100) - 1] <= CEILING(change/100), so the highest order portion of the algorithm's running time <= (C1 + C2 + C3) * (CEILING(change/100)). But that is essentially (change/100) or 1 + (change/100), which is a constant [ie 1/100] * the size of the input, so the algorithm is O(change).




  3. If it costs $ 0.63 to mail the package, the greedy approach produces a sub-optimal solution. The greedy approach would first select a 60 cent stamp, followed by a one cent stamp, a second one cent stamp, and a third one cent stamp, for a total of 4 stamps. The optimal solution is to select a 21 cent stamp, a second 21 cent stamp, and a third 21 cent stamp, for a total of 3 stamps.





  4. Part 1 - Show the adjacency lists:

    A: K, V, Y
    B: G, V
    G: B
    K: A, P, S, Y
    P: K, V
    S: K, Y
    Y: A, K, S
    V: A, B, P

    Part 2: Animation

    Part 3: Show the shortest path is from S to each node and the cost of the path.

    Destination Node Shortest Path From S Cost
    A S-Y-A 4
    B S-Y-A-V-B 9
    G S-Y-A-V-B-G 11
    K S-Y-K 6
    P S-Y-A-V-P 7
    V S-Y-A-V 6
    Y S-Y 2







  5. Here's the source code for the program written in Java: HuffmanCodes.java, Node.java, PriorityQueue.java. I've left most of my debugging code in so you can see where I printed out things. That might help you follow it a bit. It's also commented pretty well, so it should be clear. If there's something you don't understand, see me (Dave) and I'll explain it.

    Solution for the first data set: A = 11, B = 10, C = 00, D = 011, E = 010, ABL = 2.23.

    Solution for the second data set: A = 0, B = 101, C = 100, D = 111, E = 1101, F = 1100, ABL = 0.224.

    Solution for the third data set: A:100011, B:1110, C:01, D:10000, E:11110, F:110, G:100010, H:001, I:000, J:11111, K:1001, L:101, ABL: 0.32599998


    Solutions extra credit part
    symbol:frequency:code
    a:0.0827128:1110
    b:0.01558025:001101
    c:0.02291213:00000
    d:0.04903196:0001
    e:0.1208615:011
    f:0.02107916:110011
    g:0.01993355:110010
    h:0.06346661:1001
    i:0.06804903:1011
    j:0.00515523:11000011
    k:0.00927941:001100
    l:0.04903196:0010
    m:0.02554703:00111
    n:0.06346661:1010
    o:0.07457899:1101
    p:0.01672586:110001
    q:0.00114561:1100001001
    r:0.05327071:0100
    s:0.06220644:1000
    t:0.08901363:1111
    u:0.02703632:01011
    v:0.00801925:1100000
    w:0.02646351:01010
    x:0.00171841:110000101
    y:0.02348494:00001
    z:2.2912E-4:1100001000
    ABL: 4.231298