1 / 53

ITB001 Problem Solving and Programming Lecture 5

ITB001 Problem Solving and Programming Lecture 5. Faculty of Information Technology Queensland University of Technology. Aims of this lecture. Last week we saw how to break a problem down so that it can be solved by a series of repeated steps

zack
Download Presentation

ITB001 Problem Solving and Programming Lecture 5

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. ITB001Problem Solving and ProgrammingLecture 5 Faculty of Information Technology Queensland University of Technology

  2. Aims of this lecture • Last week we saw how to break a problem down so that it can be solved by a series of repeated steps • To do so we used recursive processes, in which each step is deferred until after all succeeding steps are done • We now look at an alternative problem-solving strategy, using iterative processes, in which each step is completed before the succeeding steps are done • We shall also mention the comparative efficiency of the two strategies

  3. References • Concrete Abstractions: An Introduction to Computer Science Using Scheme, Sections 3.1 to 3.3 • Structure and Interpretation of Computer Programs, Section 1.2

  4. An illustration • Another way to make paper chains of length n (where n exceeds zero) is as follows: • Make a note of the number n of links to be made • Make a single link and subtract one from the number of links to be made • Look at how many links remain to be made: • Stop if the number of links remaining is zero • Otherwise add another link to the chain, subtract one from the number of links to be made, and return to Step 3

  5. What happened? • Only one person was required to make the chain • We needed to treat the first link as a special case at the beginning • We needed to keep track of how many links remain to be made • The number of links already made plus the number remaining to be made was always equal to n

  6. The iterative strategy • The iterative problem-solving strategy works as follows: • Do a little bit of the work first, so that the remaining subproblem is smaller and has the same solution, and then solve the subproblem

  7. A simple example of problem solving using the iterative strategy • Last week we wrote a recursive procedure called total-gst to calculate the total Goods and Services Tax paid on a given list of prices • Example: (total-gst (list 150 25 45)) returns 20 • Now we will develop an iterative solution to the same problem

  8. Total GST: Designing a solution • Again we will solve the problem by separately calculating the tax paid for each item in the list and summing the results • However, to express the solution iteratively, we need to keep track not only of the prices left to be processed, but also of the subtotal calculated so far • Thus we need two parameters, the list of prices left to be processed (initially all prices), and the subtotal calculated so far (initially zero) • When there are no prices left to be processed, the subtotal is our result

  9. Total GST: Designing a solution • Action refinement: • 1. Return the sum of the tax paid for a list of items • 1.1 Initialise a list of unprocessed items to be all of the given items, and initialise a subtotal to be zero • 1.2 Return the sum of the tax paid for the list of unprocessed items added to the subtotal • 1.2.1 If the list of unprocessed items is empty, the result is the subtotal (Base Case) • 1.2.2 Otherwise, repeat Step 1.2 with the first item removed from the list of unprocessed items, and the tax paid for the first item added to the subtotal (Recursive Case)

  10. Total GST: Implementation • The following Scheme procedure implements Step 1.2 of this iterative strategy: • ;Returns the tax paid for a list of items, added to a subtotal • (define [sum-gsts prices-left subtotal] • ;If the list is empty, the result is the given subtotal • (if (empty? prices-left) • subtotal • ; Otherwise, repeat calculation with the first item • ; removed from the list, and the tax paid on the • ; first item added to the subtotal • (sum-gsts • (rest prices-left) • (+ (gst (first prices-left)) • subtotal))))

  11. Total GST: Implementation • Note that the sum-gsts procedure does not match our original requirement because it has two parameters instead of one • Therefore, we need an ‘initialisation’ procedure, as per Step 1.1, which matches the original requirement and provides the initial values for the iterative parameters: • (define [total-gst prices] • (sum-gsts prices 0)) • Initially all prices are unprocessed and the subtotal is zero

  12. The process for calculating taxes • The main steps in calculating the total tax paid on two items costing $22 and $55 are as follows: • (total-gst (list 22 55)) • (sum-gsts (list 22 55) 0) • (sum-gsts (list 55) 2) • (sum-gsts (list) 7) • 7

  13. The role of parameters in iterative procedures • For last week’s recursive total-gst procedure we needed only one parameter, but for the iterative sum-gsts procedure we needed two: • Parameter subtotal was the product of the taxes calculated so far • Parameter prices-left listed the prices remaining to be processed • The parameters in an iterative process always contain the complete ‘state’ of the computation

  14. Exercise 5-1: Length of longest word • Fill in the blanks overleaf to produce an iterative procedure that returns the length of the longest word (string) in a list, or value 1 if the given list is empty • Hints: • What information will you need to keep track of? • What is the base case and what should you return when it is reached? • What calculation must you do at each recursive step? • Built-in procedures max, string-length, first, rest and empty? will be helpful

  15. Exercise 5-1: Length of longest word (define [longest-word-length words] (longest-iter …)) (define [longest-iter …] (if … … (longest-iter …))) • Example: • (longest-word-length • (list "See" "Spot" "run")) • returns 4

  16. I’m confused — aren’t these‘iterative’ procedures recursive? • Yes, both of our procedures for calculating taxes are recursive because the procedures’ bodies refer to the procedure itself • However, last week’s total-gst procedure produces a recursive process, whereas this week’s sum-gsts procedure produces an iterative process • In fact, iteration is just a special case of recursion, and is sometimes called ‘tail’ recursion

  17. How can I tell the difference between recursive and iterative procedures? • A recursive procedure that generates a recursive process is one that defers a calculation until after a recursive application returns a value • In procedure total-gst the addition is deferred: (+ (gst …) (total-gst …)) • A recursive procedure that generates an iterative process is one that does all its calculations before it applies the recursive procedure • In sum-gsts the addition is done immediately: (sum-gsts (rest …) (+ …))

  18. An illustration: Russian dolls • The problem of assembling Russian dolls vividly illustrates the difference between recursive and iterative solutions • The recursive approach is to select the largest doll first and join it only after the smaller ones that go inside have been assembled • The dolls that have been selected but remain unassembled consume desk space • The iterative approach is to select the smallest doll first, assemble it straight away, and then move on to the next smallest

  19. Exercise 5-2: Recursionversus iteration • The two procedures overleaf both add two natural numbers • Which procedure generates a recursive process? • Which procedure generates an iterative process? • Evaluate by hand(plusX 2 1) • Evaluate by hand(plusY 2 1) • Check your evaluations with DrScheme’s debugger (and try some bigger numbers)

  20. Exercise 5-2: Recursionversus iteration (define [plusX m n] ; returns mn (if (zero? m) n (+ 1 (plusX (- m 1) n)))) (define [plusY m n] ; returns mn (if (zero? m) n (plusY (- m 1) (+ n 1))))

  21. n! n (n 1)  …  (b 1) b! a Another example: Calculatingfactorials iteratively • We already know how to calculate factorials recursively • To devise an iterative solution to the problem of calculating factorials observe that, for b less than n: • Here we will let expression a represent the part of the work already done, and expression b! be the work remaining

  22. Calculating factorials iteratively • Notice that a bigger value for ‘work done’ a means a correspondingly smaller value for ‘work remaining’ b • Also notice that ab!  (ab)  (b 1)! • This invariant property tells us that we can calculate the value of ab! by repeatedly (and simultaneously) replacing a by ab and b by b 1 • Importantly, if we are asked to calculate n!, and have finished calculating the value of expression a, then the work remaining, ‘b!’, is a factorial calculation, just like the original problem but smaller

  23. Calculating factorials iteratively • For example, to calculate 4!, which equals 24:

  24. An iterative procedure for factorials • From our desire to calculate n! we have now created a different problem to solve, namely calculating ab! • The following procedure does this using the strategy described above (define [fact-mult a b] ; returns ab! (if (zero? b) a ; when b is 0, our result is a (fact-mult (* a b) ; new value for a (- b 1)) ; new value for b )))

  25. More wishful thinking • As usual we can use wishful thinking to convince ourselves that the recursively-defined procedure works correctly • In this case we assume that ‘(fact-mult xy)’ returns the value xy! (define [fact-mult a b] (if (zero? b) a ; equals a 0! ((ab)  (b 1)!); equals ab! ))) This is not a legal Scheme expression

  26. Initialising the iterative factorial process • To solve our original problem of calculating n! we now need to use fact-mult in such a way that it produces the desired result • We can do this by observing that n! equals 1 n! (define [factorial n] (fact-mult 1 n))

  27. The iterative factorial process • For instance, the main steps involved in iteratively calculating 3! are: • (factorial 3) • (fact-mult 1 3) • (fact-mult 3 2) • (fact-mult 6 1) • (fact-mult 6 0) • 6

  28. Variations on the theme:No separate initialisation • If the iterative subproblem has a different form than the original problem, an initialisation step is needed • Procedure factorial set up the subproblem, namely finding ab!, to be solved by iterative procedure fact-mult • But procedures plusX and plusY in Exercise 5-2 didn’t need to be preceded by an initialisation step because the subproblem, adding two numbers, was the same as the original one

  29. Variations on the theme:Multiple base and recursive cases • Just as we saw for recursive processes, iterative processes also may have multiple base and recursive cases (or, equivalently, conditional behaviours in the base and recursive cases) • We can thus define iterative procedures that terminate in different ways and/or do different things at each step

  30. Exercise 5-3: Position offirst negative number • Define an iterative procedure first-neg which, given a list of numbers, returns the index at which the first negative number occurs, or 1 if the list contains no negative numbers • Assume that indexing starts at zero • Hint: You may need more than one base case • Examples: • (first-neg (list 3 8 -4 7 -2)) returns 2 • (first-neg (list 3 8 4 7 -2)) returns 4 • (first-neg (list 7 6 5 4)) returns -1

  31. Iteration seems hard — why bother? • Efficiency! • Recursive solutions are usually easier to understand than iterative ones because they mirror the ‘shape’ of the problem • But recursive processes can be much less efficient than iterative ones • Traditionally, imperative (state-oriented) programming languages emphasise iteration over recursion for this reason

  32. Recursive process: (factorial 3) (* 3 (factorial 2)) (* 3 (* 2 (factorial 1))) (* 3 (* 2 (* 1 (factorial 0)))) (* 3 (* 2 (* 1 1))) (* 3 (* 2 1)) (* 3 2) 6 Iterative process: (factorial 3) (fact-mult 1 3) (fact-mult 3 2) (fact-mult 6 1) (fact-mult 6 0) 6 Space efficiency of the recursiveand iterative factorial processes

  33. Advanced topic: Rigorouslydesigning iterative solutions • It’s easy to make mistakes when designing iterative processes • Common errors include: • ‘Off by one’ errors in which we take one too few or one too many steps • Failure to consider certain extreme cases, such as the situation where no steps are needed • Therefore, it is often worthwhile using a rigorous approach when developing iterative solutions

  34. Rigorously designing iterative solutions • A common approach is to consider carefully: • The base case (i.e., when to stop and what value to return) • The recursive case (i.e., what to do at each step and how each step makes progress towards the base case) • The loop invariant (i.e., a property of the parameters which is true initially, remains true after each step, and creates the desired result when the base case is reached)

  35. The design of the iterative factorial process • In the iterative factorial example the base case was when b was equal to zero, in which case we returned the value of a • The recursive case multiplied a by b and decremented b • The invariant property was that a times b! always equals the desired result n!: n! ab!

  36. The design of the factorialprocedure’s invariant • This invariant has the following important characteristics: • Procedure factorial makes the invariant true initially, by making a equal 1 and b equal n: n!  1 n! • Procedure fact-mult’s recursive case preserves the invariant, by making a equal to ab and b equal to b 1: ab!  (ab)  (b 1)! when b 0

  37. The design of the factorialprocedure’s invariant • When the base case is reached and the invariant holds, then the returned value a is the result we wanted: b 0 and n! ab! implies that an!

  38. Challenge exercise 5-4:Loop invariants • What is the invariant for the longest-iter procedure you developed earlier? • Express your answer as a statement relating the parameters to procedures longest-word-length and longest-iter • Explain why your invariant is true initially, is preserved by each recursive step, and produces the desired outcome when the base case is reached

  39. Efficiency case study: Exponentiation • The value of some number b raised to the (non-negative) power n can be expressed by the following recursive equation: bn 

  40. Exercise 5-5: Recursive exponentiation • Fill in the blanks to produce the equivalent recursive procedure: (define [expt b n] (if … … …)) • Evaluate by hand (expt 2 4), noting the pattern of deferred multiplications

  41. A space efficientexponentiation procedure • Once again, we can use tail recursion to create a space-efficient iterative procedure • The strategy is to maintain a product p and a counter c, initially 1 and n respectively • At each step p is multiplied by base b and c is decremented • The invariant is: bn = pbc

  42. Exercise 5-6: Iterative exponentiation • Complete the iterative exponentiation procedure: (define [expt b n] (expt-iter b n …)) (define [expt-iter b c p] (if … … (expt-iter …))) • Evaluate by hand (expt 2 4), noting how each multiplication is done as the computation proceeds

  43. Further Exercises

  44. Exercise 5-7: Profit or loss • Define an iterative procedure percent-profit which, given a non-empty list of integers representing the profits and losses on a series of jobs, returns the percentage of jobs that were profitable • Hint: Use pre-defined procedure length to get the total number of jobs • Example: • (percent-profit • (list 6 5 0 -1 -5 9 5 -2 3 7)) • returns 0.6

  45. Exercise 5-8: Flipping coins • Assume that you have a coin (for playing two-up) and want to find out which way it is biased, so you flip it several times and record the results • Define an iterative procedure commonest which takes a list of strings, "H" for heads and "T" for tails, and returns whichever of the two strings occurs most frequently in the list, or "X" if they occur equally often

  46. Exercise 5-8: Flipping coins • Examples: • (commonest (list "H" "H" "T" "H" "T" "H" "H" "H")) returns "H" • (commonest (list "T" "H" "T" "H" "T" "H" "H" "T")) returns "X"

  47. Challenge exercise 5-9: Loaded dice • Define a procedure contiguous which, given a list of numbers between 1 and 6, representing rolls of a die, returns a list containing two values, the number that occurs in the longest unbroken sequence and the length of that sequence • If there is a tie for the longest contiguous sequence your procedure should return the first one • If the list of die rolls is empty the procedure should return (list 999 0) to alert us to the fact that there is no meaningful answer • Warning: This exercise is hard!

  48. Challenge exercise 5-9: Loaded dice • Examples: • (contiguous (list 6 4 5 5 5 2 2 5 2)) returns (list 5 3) • (contiguous • (list 1 1 1 3 3 3 4 3 3 3 1 1 1 1 1)) returns (list 1 5) • (contiguous (list 2 2 2 6 6 6 6 2 2)) returns (list 6 4) • (contiguous (list 1 1 2 2 2 5 5 5)) returns (list 2 3) • (contiguous empty) returns (list 999 0)

  49. Exercise 5-10: Greatestcommon divisors • As further study, look at the greatest common divisor example in Structure and Interpretation of Computer Programs, Section 1.2.5 • This is a good example of a tricky problem that translates naturally into an iterative solution (once Euclid has pointed it out!)

  50. Exercise 5-11: Permutations revisited • In an earlier exercise you wrote a recursive procedure permutations which calculated how many ways m items can be arranged in n spaces • Rewrite your permutations procedure using an iterative strategy instead of recursion

More Related