68
CS 1321 1321

1321

  • Upload
    carson

  • View
    48

  • Download
    0

Embed Size (px)

DESCRIPTION

1321. CS. CS1321: Introduction to Programming. Georgia Institute of Technology College of Computing Lecture 19 October 29, 2001 Fall Semester. Today’s Menu. Generative Recursion: QuickSort Generative Recursion: Fractals. Last time: Generative Recursion. - PowerPoint PPT Presentation

Citation preview

Page 1: 1321

CS13211321

Page 2: 1321

CS1321:Introduction to Programming

Georgia Institute of TechnologyCollege of Computing

Lecture 19October 29, 2001

Fall Semester

Page 3: 1321

Today’s Menu1. Generative Recursion: QuickSort

2. Generative Recursion: Fractals

Page 4: 1321

Last time: Generative Recursion

Up until the last lecture, we had been working with a form of recursion that had been driven by the “structure” or characteristics of the data types passed to it.

Functions that processed a list of TAs or a tree full of numbers were “shaped” by the data definitions that they involved. A List or a Tree has built within it the idea that we will recur as we process the data as well as the idea that we will eventually terminate as we process the data.

Page 5: 1321

Processing a List (define (process-lon in-lon)

(cond ((empty? in-lon) …)

(else …(first in-lon)

…(process-lon

(rest in-lon))))

Processing a Binary Tree (define (process-BT in-BT)

(cond ((not in-BT) …)

(else …(node-data in-BT)

…(process-BT (node-left in-BT))

…(process-BT (node-right in-BT)))))

By simply having our code reflect the data definition, most of our code was written for us!

These functions are driven by the “structure” of the data definition.

Page 6: 1321

Last time: Generative Recursion

As we began to discover last time, not all functions are shaped by the structure of the data being passed in. There exists a class of recursive functions for which the structure of the data being passed in is merely a side note to the recursive process. These functions generated “new” data at each recursive step and relied on an algorithmic process to determine whether or not they should terminate.

Page 7: 1321

Last Time: Our Examples

Page 8: 1321

Last Time: Our ExamplesOur recursion in this case is driven by the location of the ball relative to the pocket, not by any intrinsic properties of the data definition.

Page 9: 1321

Last Time: Our Examples674523 14 6 3398 42

674523 14 6 3398 42

674523 14 6 3398 42

4523 1498

2398 45 14

676 33 42

676 33 42

23 98 4514 676 4233

14 23 45 98 6 33 42 67

6 14 23 33 42 45 67 98

674523 14 6 3398 42

6 14 23 33 42 45 67 98

Merge Sort, rather than being driven by definition of the list, is driven by the size of the data being passed in.

Page 10: 1321

SortingLast time we explored the idea behind merge-sort, a generative sorting algorithm that employed a “divide-and-conquer” methodology to sort a sequence of data elements into ascending order.

The algorithm for merge-sort involved splitting our list into two components of equal size, sorting each half recursively, and merging the result.

Page 11: 1321

SortingIf we examine the code, we find that the actual “sorting” of our elements didn’t take place until we had reached our termination condition (the list is empty), and were returning from our recursive calls.

(define (merge-sort lst)

(cond [(empty? lst) empty]

[else (local ((define halves (divide lst)))

(cond [(empty? (first halves))

(first (rest halves))]

[(empty? (first (rest halves)))

(first halves)]

[else (merge

(merge-sort (first halves))

(merge-sort (first

(rest halves))))]))]))

Page 12: 1321

SortingIf we examine the code, we find that the actual “sorting” of our elements didn’t take place until we had reached our termination condition (the list is empty), and were returning from our recursive calls.

(define (merge-sort lst)

(cond [(empty? lst) empty]

[else (local ((define halves (divide lst)))

(cond [(empty? (first halves))

(first (rest halves))]

[(empty? (first (rest halves)))

(first halves)]

[else (merge

(merge-sort (first halves))

(merge-sort (first

(rest halves))))]))]))

(merge

(merge-sort (first halves))

(merge-sort (first

(rest halves))))]))]))

Page 13: 1321

Quick Sort

Quick sort is another generative “divide and conquer” algorithm that involves splitting our sequence of data into parts and sorting each component recursively. Unlike merge sort, however, quick sort performs the actual sorting as the sequence is being split. In terms of performance (which we’ll formally define in the next few weeks), quick sort is considered to be a “better” algorithm than merge sort.

Page 14: 1321

Quick Sort: The basic premiseThe basic idea of quick sort involves splitting up our

list around a pivot item.

1. We arbitrarily chose an element of our list to be a pivot item.

2. We then separate our list into two components:

• those elements that are smaller than our pivot

• those elements that are larger than our pivot

3. We recursively sort the two components, and join the results together with our pivot item to form a sorted list.

Page 15: 1321

674523 14 6 3336 42

Here we start off with a list of unsorted elements. We arbitrarily choose a pivot point about which to organize our list. For the sake of expediency, let’s just choose the first element* of our list to be our pivot.

* In many theory books, there are whole chapters dedicated to the process of choosing which element to choose as the optimal pivot point. We’re just keeping things simple.

Page 16: 1321

674523 14 6 3336 42

Now, we have to organize our list about our pivot point.

Page 17: 1321

674523 14 6 3336 42

67614 36 453323 42

We start recurring on our two lists.

Page 18: 1321

674523 14 6 3336 42

67614 36 453323 42

The pivot points for each of our sub-lists.

Page 19: 1321

674523 14 6 3336 42

67614 36 453323 42

614 33 67454223

Page 20: 1321

674523 14 6 3336 42

67614 36 453323 42

614 33 674542

6 14

23

Page 21: 1321

674523 14 6 3336 42

67614 36 453323 42

614 33 674542

6 14

6 14

23

Page 22: 1321

674523 14 6 3336 42

67614 36 453323 42

614 33 674542

6 14

6 14 3323 674542

6 14

23

Page 23: 1321

674523 14 6 3336 42

67614 36 453323 42

614 3323 674542

6 14

6 14 3323 674542

6 14

6 14 3323 67454236

Page 24: 1321

674523 14 6 3336 42

6 14 3323 67454236

Page 25: 1321

Quicksort: the code1. We arbitrarily chose an element of our list to be a

pivot item.

2. We then separate our list into two components:

• those elements that are smaller than our pivot

• those elements that are larger than our pivot

3. We recursively sort the two components, and join the results together with our pivot item to form a sorted list.

Page 26: 1321

Quicksort: the code(define (quick-sort in-lon)

1. We arbitrarily chose an element of our list to be a pivot item.

2. We then separate our list into two components:

• those elements that are smaller than our pivot

• those elements that are larger than our pivot

3. We recursively sort the two components, and join the results together with our pivot item to form a sorted list.

Page 27: 1321

Quicksort: the code(define (quick-sort in-lon)

(cond ((empty? in-lon) empty)

(else (local ((define pivot (first in-lon)))

2. We then separate our list into two components:

• those elements that are smaller than our pivot

• those elements that are larger than our pivot

3. We recursively sort the two components, and join the results together with our pivot item to form a sorted list.

Page 28: 1321

Quicksort: the code(define (quick-sort in-lon)

(cond ((empty? in-lon) empty)

(else (local ((define pivot (first in-lon)))

…(smaller-items in-lon pivot)

…(larger-items in-lon pivot)

))))

3. We recursively sort the two components, and join the results together with our pivot item to form a sorted list.

Page 29: 1321

Quicksort: the code(define (quick-sort in-lon)

(cond ((empty? in-lon) empty)

(else (local ((define pivot (first in-lon)))

(append

(quick-sort

(smaller-items in-lon pivot))

(list pivot)

(quick-sort

(larger-items in-lon pivot))

)))))

Page 30: 1321

Quicksort: the code(define (quick-sort in-lon)

(cond ((empty? in-lon) empty)

(else (local ((define pivot (first in-lon)))

(append

(quick-sort

(smaller-items in-lon pivot))

(list pivot)

(quick-sort

(larger-items in-lon pivot))

)))))

The result of quick-sort is a sorted list of numbers. If one list contains items smaller than the pivot, and one contains items bigger than the pivot, the result we’re looking for should be:

Smaller + pivot + larger

Page 31: 1321

smaller-items & larger items

smaller-items is a function that takes in a list of numbers and target item and creates a list of numbers that contains only elements that are smaller than the target item.

larger-items is a function that takes in a list of numbers and target item and creates a list of numbers that contains only elements that are larger than the target item.

My goodness, those functionalities are awfully similar…

Maybe you should ponder this…

Page 32: 1321

Fractals

Perhaps one of the best-known (or at least most widely recognized) generative recursion example lies in the idea of fractals.

A formal definition of fractal is a geometrical figure consisting of an identical motif that repeats itself on an ever decreasing scale.

The images produced by fractals range greatly…

Page 33: 1321

From the bizarre

Page 34: 1321

From the bizarre

Page 35: 1321

From the bizarre

Page 36: 1321

From the bizarre

Page 37: 1321

From the bizarre

Page 38: 1321

From the bizarre

Page 39: 1321

To the Beautiful

Page 40: 1321

To the Beautiful

Page 41: 1321

To the things we see every day

Page 42: 1321

To the things we see every day

Page 43: 1321

But how does it work?

Back to the reality of the situation, how does this work and why is it called “generative recursion”.

Page 44: 1321

At each step…

At each step in the recursive process, we “generate” a new set of data based on established rules. At each step, we check to see if we’ve met a termination condition set up by our algorithm.

Page 45: 1321

Example: Sierpinski’s Triangle

Many of you may have already been exposed to Sierpinski’s triangle. It has a very

simple set of rules:

Page 46: 1321

Given a triangle…

Given a triangle with corners A, B, & C, calculate the coordinates of the midpoints of each side of the triangle. Draw lines connecting each of these midpoints.

For each new triangle generated except for the center triangle, repeat the process.

Do this until you can no longer draw triangles (you can’t see them).

Page 47: 1321
Page 48: 1321

We determine the midpoints of each of the three sides through simple mathematics

Page 49: 1321

We repeat our algorithm for each of the “corner triangles”, generating new images.

Page 50: 1321
Page 51: 1321

After only a few iterations…

Page 52: 1321

The Code

For the most part, the code for this function exists on pages 383 and 384 of your text.

Page 53: 1321

Last Fractal Examples: Sierpinksi’s triangle and

Mandelbrot

Thanks to James Hays for this code.

Page 54: 1321

Another Example

Let’s take a square. Can we represent this in Scheme?

(define-struct box(p1 p2 p3 p4))

Page 55: 1321

Another Example

Let’s take a square. Can we represent this in Scheme?

(define-struct box(p1 p2 p3 p4))

Instead of our previous model of an upper-left posn and an edge length, we’ll just use 4 posns.

Page 56: 1321

Another Example

Now, let’s take a fixed value, some percentage of the box edge length.

90%

10%

Page 57: 1321

Another Example

Do this for all sides . . .

90%

10%

Page 58: 1321

Another Example

Do this for all sides . . . and use the resulting points as the data for a new square.

90%

10%

Page 59: 1321

Another Example

Wash, rinse, repeat.

Page 60: 1321

Another Example

How would we write this in code?

Page 61: 1321

Another ExampleImplementation...

(define (draw-box in-box)...

The structure is already given.

(define-struct box(p1 p2 p3 p4))

We know there must be a function to draw a box. The details of this are not interesting.

Page 62: 1321

Another ExampleWe also need a function that takes in a box, and returns a new, smaller box.

(define (move-box b %move) (local ((define p1 (box-p1 b)) (define p2 (box-p2 b)) (define p3 (box-p3 b)) (define p4 (box-p4 b)) (define (adjust-points a b %move) (make-posn (+ (* %move (posn-x a)) (* (- 1 %move) (posn-x b))) (+ (* %move (posn-y a)) (* (- 1 %move) (posn-y b)))))) (make-box (adjust-points p1 p2 %move) (adjust-points p2 p3 %move) (adjust-points p3 p4 %move) (adjust-points p4 p1 %move))))

Page 63: 1321

Another Example

Another Example

Wash, rinse, repeat.

We know that there’s a recursive process at work.

That’s the most interesting part of this problem.

When does it terminate?

Page 64: 1321

Another Example

Another Example

Wash, rinse, repeat.

We know that there’s a recursive process at work.

That’s the most interesting part of this problem.

When does it terminate? It likely terminates when the size of the box is too small to bother with.

Page 65: 1321

Another ExampleAnother Example

Wash, rinse, repeat.

(define (draw-spirals in-box %move) (cond [ <trivial-case?><trivial-case?> true ] [ else <draw-the-box><draw-the-box> (draw-spirals <update-the-box><update-the-box> %move) ]))

When does it terminate? It likely terminates when the size of the box is too small to bother with.

Page 66: 1321

Another ExampleAnother Example

Wash, rinse, repeat.

(define (draw-spirals in-box %move) (cond [ <trivial-case?><trivial-case?> true ] [ else (draw-box in-box) (draw-spirals (move-box in-box %move) %move) ]))

We already have functions for drawing the box and updating the box.

Page 67: 1321

Another ExampleAnother Example

Wash, rinse, repeat.

(define (draw-spirals in-box %move) (cond [ <trivial-case?><trivial-case?> true ] [ else (draw-box in-box) (draw-spirals (move-box in-box %move) %move) ]))

The ‘trivial’ case function really just tests if the current recursive call has generated another need to recur.

Page 68: 1321

Another ExampleAnother Example

Wash, rinse, repeat.

(define (draw-spirals in-box %move) (cond [ (too-small? in-box)(too-small? in-box) true ] [ else (draw-box in-box) (draw-spirals (move-box in-box %move) %move) ]))

(define (too-small? in-box) (> 20 (distance (posn-x (box-p1 in-box)) (posn-x (box-p2 in-box)) (posn-y (box-p1 in-box)) (posn-y (box-p2 in-box)))))

(define (distance x1 x2 y1 y2) (sqrt (+ (square (- x1 x2)) (square (- y1 y2)))))