Recursion: Genome 559: Introduction To Statistical and Computational Genomics
Recursion: Genome 559: Introduction To Statistical and Computational Genomics
Default Arguments
def printMulti(text, n=3):
Keyword Arguments
runBlast(“my_fasta.txt”, matrix=“PAM40”)
A quick review – cont’
Modules:
A module is a file containing a set of related functions
Python has numerous standard modules
Bubble sort
Swap two adjacent elements whenever they are not in
the right order
Merge sort
???
The merge sort algorithm
1. Split your list into two halves
Well …
We can! It works! And it is called a recursive function!
Why is it working?
# This function calculated n!
def factorial(n):
if n==0:
return 1
else:
return n * factorial(n-1)
factorial(5)
120
5 * factorial(4)
24
4 * factorial(3)
6
3 * factorial(2)
2
2 * factorial(1)
1
1 * factorial(0)
1
1
Recursion and recursive functions
A function that calls itself, is said to be a recursive
function (and more generally, an algorithm that is defined in
terms of itself is said to use recursion or be recursive)
reverse
d l r o w o l l e + h
See how simple and
elegant it is! No loops!
s[1:] returns all but the first character of the string. We reverse this
part (s[1:]) and then concatenate the first character (s[0]) to the end.
String reversal - D’oh!
# This function reverses a string
def reverse(s):
return reverse(s[1:]) + s[0]
Binary search
How long does it take for this algorithm to find the query
item (or to determine it is not in the list)?
Towers of Hanoi
There are three posts and 64 concentric disks shaped
like a pyramid.
The goal is to move the disks from post A to post B,
following these three rules:
1. You can move only one disk at a time.
2. A disk may not be “set aside”. It may only be stacked on
one of the three posts.
3. A larger disk may never be placed on top of a smaller one.
A B C
Towers of Hanoi
Towers-of-Hanoi algorithm (for an “n disk tower”)
1. Move an “n-1 disk tower” from source-post to resting-post
(use the tower-of-hanoi algorithm)
2. Move 1 disk from source-post to destination-post
3. Move an “n-1 disk tower” from resting-post to destination-
post (use the tower-of-hanoi algorithm)
print node.value, 10
preorder(node.left)
preorder(node.right)
preorder(root) 3 12
10 3 1 7 6 9 12 15
1 7 15
6 9
Traversing a phylogenetic tree
Recursion is extremely useful when processing a data
structure that is recursive by nature.
def preorder(node):
if node == None:
return
print node.value, 10
preorder(node.left)
preorder(node.right)
preorder(root) 3 12
10 3 1 7 6 9 12 15
def postorder(node):
if node == None:
return
1 7 15
postorder(node.left)
postorder(node.right)
print node.value, 6 9
postorder(root)
1 6 9 7 3 15 12 10
Finally,
let’s get back to our merge sort
The merge sort algorithm
1. Split your list into two halves
2. Sort the first half (using
merge sort)
3. Sort the second half (using
merge sort)
4. Merge the two sorted halves,
maintaining a sorted order
# Merge two sorted lists
The merge sort algorithm def merge(list1, list2):
merged_list = []
1. Split your list into two halves i1 = 0
i2 = 0
2. Sort the first half (using
4 helper function
# Merge
merge sort) while i1 < len(list1) and i2 < len(list2):
if list1[i1] <= list2[i2]:
merged_list.append(list1[ii])
3. Sort the second half (using i1 += 1
merge sort) else:
merged_list.append(list2[i2])
i2 += 1
4. Merge the two sorted halves,
# One list is done, move what's left
maintaining a sorted order while i1 < len(list1):
merged_list.append(list1[i1])
i1 += 1
while i2 < len(list2):
merged_list.append(list2[i2])
i2 += 1
return merged_list
2 first_half_sorted = sort_r(first_half)
second_half_sorted = sort_r(second_half)
3
sorted_list = merge \
List of size 1. 4 (first_half_sorted, second_half_sorted)
Base case return sorted_list
else:
return list
Recursion vs. Iteration
There are usually similarities between an iterative
solutions (e.g., looping) and a recursive solution.
In fact, anything that can be done with a loop can be done
with a simple recursive function!
In many cases, a recursive solution can be easily converted
into an iterative solution using a loop (but not always).
my_prog.py
my_list = [1, 3, 5, 7, 9, 11]
For example:
“detartrated”
“olson in oslo”
“step on no pets”
Solution #2
def is_palindrome(word):
l = len(word)
if l <= 1:
return True
else:
return word[0] == word[l-1] and is_palindrome(word[1:l-1])
>>>is_palindrome("step on no pets")
True
>>>is_palindrome("step on no dogs")
False
>>>is_palindrome("12345678987654321")
True
>>>is_palindrome("1234")
False
Challenge problems
1. Write a recursive function that prime factorize s an
integer number.
(The prime factors of an integer are the prime numbers that divide the
integer exactly, without leaving a remainder).
Your function should print the list of prime factors:
>>> prime_factorize(5624)
2 2 2 19 37
>>> prime_factorize(277147332)
2 2 3 3 3 3 3 7 7 11 23 23
Note: you can use a for loop to find a divisor of a number but the
factorization process itself should be recursive!
def prime_factorize(number):
print divisor,
prime_factorize(277147332)
Challenge solution 2
import math
factors.append(divisor)
factors = []
prime_factorize(277147332,factors)
print factors