37
Recursion Alaa K. Al-Makhzoomy Faculty of IT - WISE

Recursion - Computer Algorithms

Embed Size (px)

Citation preview

Page 1: Recursion - Computer Algorithms

Recursion

Alaa K. Al-Makhzoomy – Faculty of IT - WISE

Page 2: Recursion - Computer Algorithms

1. Motivation

2

Suppose you want to find all the files under a directory that contains a particular word. How do you solve this problem?

There are several ways to solve this problem.

An intuitive solution is to

use recursion by searching

the files in the subdirectories

recursively.

Page 4: Recursion - Computer Algorithms

3. Motivation – Solving Complex Problems

4

The Eight Queens puzzle consists on placing eight queens on a chessboard

such that no two queens are on the same row, same column, or same

diagonal, as shown in figure below.

Your turn: Try placing n Queens on an n*n board

Page 5: Recursion - Computer Algorithms

Typical Example - Computing Factorial

5

Notation

n ! = n * (n-1)!

factorial( n ) = n * factorial( n-1 );

Example: Compute the value of 4!

factorial(4) = 4 * factorial( 3 )

= 4 * ( 3 * factorial(2) )

= 4 * ( 3 * (2 * factorial(1)) )

= 4 * ( 3 * ( 2 * (1 * factorial(0))))

= 4 * (3 * ( 2 * ( 1 * 1 )))

= 4 * (3 * ( 2 * 1))

= 4 * (3 * 2 )

= 4 * 6

= 24

Page 6: Recursion - Computer Algorithms

Trace Recursive factorial

6

Main method

3

Space Required

for factorial(3)

Space Required

for factorial(2)

Space Required

for factorial(4)

4

Space Required

for factorial(3)

Space Required

for factorial(2)

Space Required

for factorial(1)

5 Stack

return 1

factorial(4)

return 4 * factorial(3)

return 3 * factorial(2)

return 2 * factorial(1)

return 1 * factorial(0)

Step 9: return 24 Step 0: executes factorial(4)

Step 1: executes factorial(3)

Step 2: executes factorial(2)

Step 3: executes factorial(1)

Step 5: return 1

Step 6: return 1

Step 7: return 2

Step 8: return 6

Step 4: executes factorial(0)

Recursive descend

Backtrack

Page 7: Recursion - Computer Algorithms

Computing Factorial

private static int fact(int n) {

if ( n == 0 )

return 1;

else

return n*fact(n-1);

}

Page 8: Recursion - Computer Algorithms

factorial(4) Stack Trace

8

Page 9: Recursion - Computer Algorithms

Other Example – Recursive Summation

9

f(0) = 0;

f(n) = n + f(n-1);

Example:

f (12) = 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12

Observe that f(12) = 12 + f(11), and

f (11) = 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11

Which in turn can be computed as f(11) = 11 + f(10)

Likewise, f(10) = 10 + f(9), and so on, until f(0) = 0 is discovered

f(11)

f(10)

Recursive sum of first n numbers

1

00

nn

ini

Page 10: Recursion - Computer Algorithms

Fibonacci Numbers

10

Fibonacci series: 0 1 1 2 3 5 8 13 21 34 55 89…

indices: 0 1 2 3 4 5 6 7 8 9 10 11

fib(0) = 0;

fib(1) = 1;

fib(index) = fib(index -1) + fib(index -2); index >=2

fib(3) = fib(2) + fib(1)

= (fib(1) + fib(0)) + fib(1)

= (1 + 0) +fib(1)

= 1 + fib(1)

= 1 + 1 = 2

Page 11: Recursion - Computer Algorithms

Fibonacci Numbers

11

private static int fib(int n) {

if ((n == 1) || (n == 0))

return n;

else

return fib(n - 2) + fib(n - 1);

}

Page 12: Recursion - Computer Algorithms

Fibonnaci Numbers, cont.

12

Page 13: Recursion - Computer Algorithms

Fibonnaci Numbers.

13

Fibonacci Numbers

1 (Jan) C1 1 (Feb) C1 2 (Mar) C1 C1,1 3 (Apr) C1 C1,2 C1,1

5 (May) C1 C1,3 C1,2 C1,1 C1,1,1 8 (Jun) C1 C1,4 C1,3 C1,2 C1,2,1 C1,1 C1,1,2 C1,1,1 13 (Jul) 21 (Aug) 34 (Sep) 55 (Oct) 89 (Nov) 144 (Dec)

C x,y

Represents a couple of male & female rabbits.

C1,2 is the second offspring pair descending

from couple 1.

Fibonacci sequence first appears in the book Liber Abaci (1202) by Leonardo of Pisa, known as Fibonacci.

Fibonacci considers the growth of an idealized rabbit population, assuming that: a newly born pair of rabbits, one male, one female, are put in a field; rabbits are able to mate at the age of one month so that at the end of its second month a female can produce another pair of rabbits; rabbits never die and a mating pair always produces one new pair (one male, one female) every month from the second month on. The puzzle that Fibonacci posed was: how many pairs will there be in one year? Taken from: http://en.wikipedia.org/wiki/Fibonacci_number

Page 14: Recursion - Computer Algorithms

Fibonnaci

Numbers.

14 Images from: mathacademy.com,

Fibonacci Spiral

1, 1, 2, 3, 5, 8, 13, 21, 34, 55, …

Known as “The fingerprint of God”

See an interesting video at (watch at your own risk!) http://www.youtube.com/watch?v=e9MwNm0gXd8

Page 15: Recursion - Computer Algorithms

Characteristics of Recursion

15

All recursive methods have the following characteristics:

One or more base cases (the simplest case) are used to stop recursion

(boundary conditions). Every recursive call reduces the original problem, bringing it

increasingly closer to a base case until it becomes that case.

In general, to solve a problem using recursion,

1. you break it into subproblems. 2. If a subproblem resembles the original problem, you can apply the same approach to

solve the subproblem recursively. 3. This subproblem is almost the same as the original problem in nature with a smaller

size.

Page 16: Recursion - Computer Algorithms

Problem Solving Using Recursion

16

Let us consider a simple problem of printing a message for n times.

You can break the problem into two subproblems:

1. One is to print the message one time and the other is to print the message for n-1 times.

2. The second problem is the same as the original problem with a smaller size.

3. The base case for the problem is n==0.

private static void printMsg(String msg, int times) {

// printing a message a number of times if (times==0) return; System.out.println(times + " " + msg); printMsg(msg, times-1);

}

Page 17: Recursion - Computer Algorithms

private static boolean isPalindrome ( String str ) { if (str.length() == 0 || str.length() == 1) return true; char first = str.charAt(0); char last = str.charAt(str.length() - 1); if (first != last) return false; else { str = str.substring(1, str.length() - 1); return isPalindrome( str ); } }

Version1: Palindrome

17

Examples: 100a001, MADAMIMADAM, abccba are palindromes.

Page 18: Recursion - Computer Algorithms

Version2: Recursive Helper Methods

18

Examples: 100a001, MADAMIMADAM, abccba are palindromes.

public static boolean isPalindrome(String s) {

return isPalindrome(s, 0, s.length() - 1);

}

public static boolean isPalindrome(String s, int low, int high) {

if (high <= low) // Base case

return true;

else if (s.charAt(low) != s.charAt(high)) // Base case

return false;

else

return isPalindrome(s, low + 1, high - 1);

}

Page 19: Recursion - Computer Algorithms

Directory Size

19

This section presents a problem that is difficult to solve without using recursion.

The problem is to find the size of a directory. The size of a directory is the sum of the sizes of all files in the directory. A directory may contain subdirectories.

directory

...

1f

1

2f

1

mf

1

1d

1

2d

1

nd

1

...

)(...)()()(...)()()( 2121 nm dsizedsizedsizefsizefsizefsizedsize

Page 20: Recursion - Computer Algorithms

Directory Size

20

public class DirectorySize {

public static void main(String[] args) {

System.out.print("Enter a file or a directory: ");

java.util.Scanner input = new java.util.Scanner(System.in);

String s = input.nextLine();

try {

System.out.println( directorySize( new File(s) ) );

}

catch (IOException ex) {

System.out.println(ex.toString());

}

}

public static long directorySize(File file) throws java.io.FileNotFoundException{

if (!file.exists())

throw new java.io.FileNotFoundException(file + " not found");

if (file.isFile()) {

return file.length();

}

else {

File[] files = file.listFiles();

long size = 0;

for (int i = 0; i < files.length; i++)

size += directorySize(files[i]);

return size;

}

}

}

Page 21: Recursion - Computer Algorithms

Towers of Hanoi

21

There are n disks labeled 1, 2, 3, . . ., n, and three towers labeled

A, B, and C.

No disk can be on top of a smaller disk at any time.

All the disks are initially placed on tower A.

Only one disk can be moved at a time, and it must be the top disk

on the tower.

Invented by french

mathematician

Edouard Lucas (1842)

Image from Wikipedia 7/8/2011

Page 22: Recursion - Computer Algorithms

Towers of Hanoi, cont.

22

A B

Original position

C A B

Step 4: Move disk 3 from A to B

C

A B

Step 5: Move disk 1 from C to A

C A B

Step 1: Move disk 1 from A to B

C

A C B

Step 2: Move disk 2 from A to C

A B

Step 3: Move disk 1 from B to C

C A B

Step 7: Mve disk 1 from A to B

C

A B

Step 6: Move disk 2 from C to B

C

Page 23: Recursion - Computer Algorithms

Solution to Towers of Hanoi

23

The Towers of Hanoi problem can be decomposed into three subproblems.

A B

Original position

C

.

.

.

A B

Step 1: Move the first n-1 disks from A to C recursively

C

.

.

.

A B

Step2: Move disk n from A to C

C

.

.

.

A B

Step3: Move n-1 disks from C to B recursively

C

.

.

.

n-1 disks

n-1 disks

n-1 disks

n-1 disks

Step 2. Move disk n from A to B

Page 24: Recursion - Computer Algorithms

Solution to Towers of Hanoi

24

1. Move the first n - 1 disks from A to C with the assistance of tower B.

2. Move disk n from A to B.

3. Move n - 1 disks from C to B with the assistance of tower A.

Page 25: Recursion - Computer Algorithms

Solution to Towers of Hanoi

25

public static void main(String[] args) { int n = 4; // moving disks from A to B using C as auxiliary tower System.out.println("Towers of Hanoi. The moves are:"); moveDisks(n, 'A', 'B', 'C'); } private static void moveDisks( int n, char fromTower, char toTower, char auxTower) { if (n == 1) System.out.println("Move disk " + n + " from " + fromTower + " to " + toTower); else { moveDisks(n-1, fromTower, auxTower, toTower); System.out.println("Move disk " + n + " from " + fromTower + " to " + toTower); moveDisks(n-1, auxTower, toTower, fromTower); }

Page 26: Recursion - Computer Algorithms

Greatest Common Divisor - GCD

26

gcd(2, 3) = 1

gcd(2, 10) = 2

gcd(25, 35) = 5

gcd(14, 28) = 14

Approach 1: Brute-force, start from min(n, m) down to 1, to check if a number is common divisor for both m and n, if so, it is the greatest common divisor.

Approach 2: Euclid’s algorithm

Approach 3: Recursive method

GCD

is the largest positive integer that divides

The numbers without a remainder

Page 27: Recursion - Computer Algorithms

Approach 2: Euclid’s algorithm

27

// Get absolute value of m and n;

t1 = Math.abs(m);

t2 = Math.abs(n);

// r is the remainder of t1 divided by t2;

r = t1 % t2;

while (r != 0) {

t1 = t2;

t2 = r;

r = t1 % t2;

}

// When r is 0, t2 is the greatest common

// divisor between t1 and t2

return t2;

Page 28: Recursion - Computer Algorithms

Approach 3: Recursive Method

28

gcd(m, n) = n if ( m % n = 0 );

gcd(m, n) = gcd(n, m % n); otherwise;

private static int gcd(int m, int n) { if (m % n == 0) return n; else return gcd(n, m % n); }

Page 29: Recursion - Computer Algorithms

29

Knapsack Problem

Load a knapsack with any number of items without exceeding its capacity.

//knapsack problem. Simple case - no optimization

ArrayList<Integer> items = new ArrayList<Integer> (

Arrays.asList(8, 2, 9, 4, 1, 5, 3, 4, 2, 6, 7));

ArrayList<Integer> solution = new ArrayList<Integer>();

knapsack(16, solution, items);

for (int n : solution){

System.out.println("Knapsack: " + n );

}

Picture taken from: http://en.wikipedia.org/wiki/Knapsack_problem

Page 30: Recursion - Computer Algorithms

30

Knapsack Problem

Load a knapsack with any number of items without exceeding its capacity. private static void knapsack(int maxWeight, ArrayList<Integer> solution, ArrayList<Integer> items) { if ((maxWeight >= 0 ) && (items.size()>0) ) { int item = items.remove(0); solution.add(0, item); knapsack(maxWeight-item, solution, items); } else { int item = solution.remove(0); if (items.size()==0) return; else{ knapsack(maxWeight+item, solution, items); } } }

Picture taken from: http://en.wikipedia.org/wiki/Knapsack_problem

Page 31: Recursion - Computer Algorithms

Fractals?

31

A fractal is a geometrical figure

just like triangles, circles, and

rectangles, but fractals can be

divided into parts, each of which is

a reduced-size copy of the whole.

Page 32: Recursion - Computer Algorithms

Sierpiński Triangle

32

1. It begins with an equilateral triangle, which is considered to be the Sierpinski fractal of order (or level) 0, as shown in Figure (a).

2. Connect the midpoints of the sides of the triangle of order 0 to create a Sierpinski triangle of order 1, as shown in Figure (b).

3. Leave the center triangle intact. Connect the midpoints of the sides of the three other triangles to create a Sierpinski of order 2, as shown in Figure (c).

4. You can repeat the same process recursively to create a Sierpinski triangle of order 3, 4, ..., and so on, as shown in Figure (d).

Page 33: Recursion - Computer Algorithms

Sierpinski Triangle Solution

33

p1

p3 p2

midBetweenP1P2 midBetweenP3P1

midBetweenP2P3

Page 34: Recursion - Computer Algorithms

Sierpinski Triangle Solution

34

public void drawTriangle (int order, Point p1, ponit p2, Point p3) if (order == 0) return; else { // calculate midpoints of triangle p1-p2-p3 p12 = midPoint (p1, p2); p13 = midPoint(p1, p3); p23 = midPoint(p2, p3); // draw inner Sierpinski triangles of smaller order drawTriangle(order-1, p1, p12, p13); drawTriangle(order-1, p12, p2, p23); drawTriangle(order-1, p13, p23, p3); } }

Page 35: Recursion - Computer Algorithms

Eight Queens

35

0

4

7

5

2

6

1

3

queens[0]

queens[1]

queens[2]

queens[3]

queens[4]

queens[5]

queens[6]

queens[7]

Page 36: Recursion - Computer Algorithms

Eight Queens

36

0 1 2 3 4 5 6 7

0

1

2

3

4

5

6

7

upright diagonal

upleft

check

colum

n

Page 37: Recursion - Computer Algorithms

Eight Queens

37

// start by calling: search(0); // search for a solution starting on specified row private static boolean search(int row){ if (row == SIZE) return true; for (int column=0; column < SIZE; column++){ queens[row] = column; //place a queen at row,column if (isValid(row, column) && search(row+1)){ System.out.println("Queen at: " + row + " : " + column); return true; } } return false; }//search // check if a queen can be placed at row i and column j private static boolean isValid(int row, int column){ for(int i=1; i<= row; i++){ if ( queens[row-i] == column //check column || queens[row-i] == column - i //check upleft diagonal || queens[row-i] == column + i )//check upright diagonal return false; } return true; }//isValid