Recursion Genome 559: Introduction to Statistical and Computational Genomics Elhanan Borenstein.

Slides:



Advertisements
Similar presentations
Genome 559: Introduction to Statistical and Computational Genomics
Advertisements

Algorithms Analysis Lecture 6 Quicksort. Quick Sort Divide and Conquer.
Chapter 4: Divide and Conquer Master Theorem, Mergesort, Quicksort, Binary Search, Binary Trees The Design and Analysis of Algorithms.
Factorial Recursion stack Binary Search Towers of Hanoi
Recursion CSC 220: Data Structure Winter Introduction A programming technique in which a function calls itself. One of the most effective techniques.
CMPS1371 Introduction to Computing for Engineers SORTING.
Sorting Chapter Sorting Consider list x 1, x 2, x 3, … x n We seek to arrange the elements of the list in order –Ascending or descending Some O(n.
Recursion Introduction to Computing Science and Programming I.
Recursion. Objectives At the conclusion of this lesson, students should be able to Explain what recursion is Design and write functions that use recursion.
©The McGraw-Hill Companies, Inc. Permission required for reproduction or display. ETC - 1 What comes next? Recursion (Chapter 15) Recursive Data Structures.
Recursion.
Chapter 15 Recursive Algorithms. 2 Recursion Recursion is a programming technique in which a method can call itself to solve a problem A recursive definition.
1 Chapter 7 Recursion. 2 What Is Recursion? l Recursive call A method call in which the method being called is the same as the one making the call l Direct.
Recursion Chapter 7. Chapter 7: Recursion2 Chapter Objectives To understand how to think recursively To learn how to trace a recursive method To learn.
Recursion Chapter 7. Chapter 7: Recursion2 Chapter Objectives To understand how to think recursively To learn how to trace a recursive method To learn.
Recursion, Complexity, and Searching and Sorting By Andrew Zeng.
Copyright © 2007 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Chapter 12: Recursion Problem Solving, Abstraction, and Design using C++
Chapter 13 Recursion. Topics Simple Recursion Recursion with a Return Value Recursion with Two Base Cases Binary Search Revisited Animation Using Recursion.
Recursion Chapter 7. Chapter Objectives  To understand how to think recursively  To learn how to trace a recursive method  To learn how to write recursive.
Recursion.
Copyright © 2010 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Starting Out with Programming Logic & Design Second Edition by Tony Gaddis.
CSCE 3110 Data Structures & Algorithm Analysis Sorting (I) Reading: Chap.7, Weiss.
Recursion Chapter 11. The Basics of Recursion: Outline Introduction to Recursion How Recursion Works Recursion versus Iteration Recursive Methods That.
1 Programming with Recursion. 2 Recursive Function Call A recursive call is a function call in which the called function is the same as the one making.
Lecturer: Dr. AJ Bieszczad Chapter 11 COMP 150: Introduction to Object-Oriented Programming 11-1 l Basics of Recursion l Programming with Recursion Recursion.
1 CS 177 Week 16 Recitation Recursion. 2 Objective To understand and be able to program recursively by breaking down a problem into sub problems and joining.
Recursion Textbook chapter Recursive Function Call a recursive call is a function call in which the called function is the same as the one making.
Sudeshna Sarkar, IIT Kharagpur 1 Functions : Recursion Lecture
Chapter 13 Recursion. Learning Objectives Recursive void Functions – Tracing recursive calls – Infinite recursion, overflows Recursive Functions that.
 2006 Pearson Education, Inc. All rights reserved Searching and Sorting.
Recursion Recursion Chapter 12. Outline n What is recursion n Recursive algorithms with simple variables n Recursion and the run-time stack n Recursion.
CSIS 123A Lecture 9 Recursion Glenn Stevenson CSIS 113A MSJC.
CSC 221: Recursion. Recursion: Definition Function that solves a problem by relying on itself to compute the correct solution for a smaller version of.
By: Lokman Chan Recursive Algorithm Recursion Definition: A function that is define in terms of itself. Goal: Reduce the solution to.
Sorting and Searching. Selection Sort  “Search-and-Swap” algorithm 1) Find the smallest element in the array and exchange it with a[0], the first element.
Chapter 11Java: an Introduction to Computer Science & Programming - Walter Savitch 1 Chapter 11 l Basics of Recursion l Programming with Recursion Recursion.
1 Searching and Sorting Searching algorithms with simple arrays Sorting algorithms with simple arrays –Selection Sort –Insertion Sort –Bubble Sort –Quick.
© Janice Regan, CMPT 128, February CMPT 128: Introduction to Computing Science for Engineering Students Recursion.
Data Structures - CSCI 102 Selection Sort Keep the list separated into sorted and unsorted sections Start by finding the minimum & put it at the front.
Copyright © 2009 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Chapter 12 Recursion.
Course Code #IDCGRF001-A 5.1: Searching and sorting concepts Programming Techniques.
Recursion COMP x1 Sedgewick Chapter 5. Recursive Functions problems can sometimes be expressed in terms of a simpler instance of the same problem.
Recursion. Objectives At the conclusion of this lesson, students should be able to Explain what recursion is Design and write functions that use recursion.
CS 116 Object Oriented Programming II Lecture 13 Acknowledgement: Contains materials provided by George Koutsogiannakis and Matt Bauer.
1 CSC 143 Recursion [Reading: Chapter 17]. 2 Recursion  A recursive definition is one which is defined in terms of itself.  Example:  Sum of the first.
Chapter 13 Recursion Copyright © 2016 Pearson, Inc. All rights reserved.
Recursion Version 1.0.
Recursion Topic 5.
Chapter 15 Recursion.
CprE 185: Intro to Problem Solving (using C)
Introduction to Computing Science and Programming I
Chapter 15 Recursion.
CS 1321.
Recursive Thinking Chapter 9 introduces the technique of recursive programming. As you have seen, recursive programming involves spotting smaller occurrences.
Data Structures Recursion CIS265/506: Chapter 06 - Recursion.
Teach A level Computing: Algorithms and Data Structures
Recursive Thinking Chapter 9 introduces the technique of recursive programming. As you have seen, recursive programming involves spotting smaller occurrences.
Chapter 4: Divide and Conquer
Calculate n! Multiply my number by the factorial of the rest of the numbers. if( num > 2 ) return num * factorialR2( num - 1 ); else return 2;
賦得古原草送別 ~白居易 離離原上草,一歲一枯榮。 野火燒不盡,春風吹又生。 遠芳侵古道,晴翠接荒城。 又送王孫去,萋萋滿別情。
24 Searching and Sorting.
Algorithm Efficiency and Sorting
Lecture 11 Algorithm Design
CSCE 3110 Data Structures & Algorithm Analysis
Chapter 3 :Recursion © 2011 Pearson Addison-Wesley. All rights reserved.
CSCE 3110 Data Structures & Algorithm Analysis
Chapter 13 Recursion Copyright © 2010 Pearson Addison-Wesley. All rights reserved.
CSCE 3110 Data Structures & Algorithm Analysis
ITEC324 Principle of CS III
Presentation transcript:

Recursion Genome 559: Introduction to Statistical and Computational Genomics Elhanan Borenstein

A quick review  Returning multiple values from a function return [sum, prod]  Pass-by-reference vs. pass-by-value  Python passes arguments by reference  Can be used (carefully) to edit arguments “in-place”  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  It is easy to create and use your own modules:  Just put your functions in a separate file  To use a module, you first have to import it: import utils  Use the dot notation: utils.makeDict()

So … what is a recursion and what is it good for?

Sorting algorithm  A sorting algorithm takes a list of elements in an arbitrary order, and sort these elements in an ascending order.  Commonly used algorithms:  Naïve sorting (a.k.a. selection sort) Find the smallest element and move it to the beginning of the list  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 2.Sort the first half 3.Sort the second half 4.Merge the two sorted halves, maintaining a sorted order

Divide-and-conquer  The basic idea behind the merge sort algorithm is to divide the original problem into two halves, each being a smaller version of the original problem.  This approach is known as divide and conquer  Top-down technique  Divide the problem into independent smaller problems  Solve smaller problems  Combine smaller results into a larger result thereby “conquering” the original problem.

Merge sort – the nitty gritty The merge sort algorithm 1.Split your list into two halves 2.Sort the first half 3.Sort the second half 4.Merge the two sorted halves, maintaining a sorted order That’s simple Careful bookkeeping, but still simple ??? If I knew how to sort, I wouldn’t be here in the first place?!?

Merge sort – the nitty gritty The merge sort algorithm 1.Split your list into two halves 2.Sort the first half 3.Sort the second half 4.Merge the two sorted halves, maintaining a sorted order That’s simple ??? So … how are we going to sort the two smaller lists? Here’s a crazy idea: let’s use merge sort to do this def mergeSort(list): half1  first half of list half2  second half of list half1_sorted = mergeSort(half1) half2_sorted = mergeSort(half2) list_sorted = merge(half1_sorted,half2_sorted) return list_sorted Careful bookkeeping, but still simple

You must be kidding, right? this is making me dizzy!  WHAT?  This function has no loop?  It seems to refer to itself!  Where is the actual sort?  What’s going on??? def mergeSort(list): half1  first half of list half2  second half of list half1_sorted = mergeSort(half1) half2_sorted = mergeSort(half2) list_sorted = merge(half1_sorted,half2_sorted) return list_sorted

Let’s take a step back …

Factorial # This function calculated n! def factorial(n): f = 1 for i in range(1,n+1): f *= i return f >>> print factorial(5) 120 >>> print factorial(12)

Factorial  But … there is an alternative recursive definition:  So … can we write a function that calculates n! using this approach?  Well … We can! It works! And it is called a recursive function! # This function calculated n! def factorial(n): if n==0: return 1 else: return n * factorial(n-1)

Why is it working? # This function calculated n! def factorial(n): if n==0: return 1 else: return n * factorial(n-1) factorial(5) 5 * factorial(4) 4 * factorial(3) 3 * factorial(2) 2 * factorial(1) 1 * factorial(0)

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) (A call to the function “recurs” within the function; hence the term “recursion”)  In may real-life problems, recursion provides an intuitive and natural way of thinking about a solution and can often lead to very elegant algorithms.

mmm…  If a recursive function calls itself in order to solve the problem, isn’t it circular? (in other words, why doesn’t this result in an infinite loop?)  Factorial, for example, is not circular because we eventually get to 0!, whose definition does not rely on the definition of another factorial and is simply 1.  This is called a base case for the recursion.  When the base case is encountered, we get a closed expression that can be directly computed.

Defining a recursion  Every recursive algorithm must have two key features: 1.There are one or more base cases for which no recursion is applied. 2.All recursion chains eventually end up at one of the base cases. The simplest way for these two conditions to occur is for each recursion to act on a smaller version of the original problem. A very small version of the original problem that can be solved without recursion then becomes the base case.

This is fun! Let’s try to solve (or at least think of) other problems using recursion

String reversal # This function reverses a string def reverse(s): return reverse(s[1:]) + s[0]  Divide the string into first character and all the rest  Reverse the “rest” and append the first character to the end of it helloworld h dlrowolle + reverse 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. See how simple and elegant it is! No loops!

String reversal - D’oh! # This function reverses a string def reverse(s): return reverse(s[1:]) + s[0] >>> print reverse(“hello world”) What just happened? There are 1000 lines of errors! >>> print reverse(“hello world”) Traceback (most recent call last): File " ", line 1, in File " ", line 2, in reverse. File " ", line 2, in reverse RuntimeError: maximum recursion depth exceeded

String reversal – Duh!  Remember: To build a correct recursive function, we need a base case that doesn’t use recursion! We forgot to include a base case, so our program is an infinite recursion. Each call to “reverse” contains another call to reverse, so none of them return. Each time a function is called it takes some memory. Python stops it at 1000 calls, the default “maximum recursion depth.”  What should we use for our base case?

String reversal - Yeah  Since our algorithm is creating shorter and shorter strings, it will eventually reach a stage when S is of length 1 (one character).  Since a string of length 1 is its own reverse, we can use it as the base case. # This function reverses a string def reverse(s): if len(s) == 1: return s else: return reverse(s[1:])+s[0] >>> print reverse(“hello world”) “dlrow olleh”

Search a sorted list (think phonebook)  How would you search a sorted list to check whether a certain item appears in the list and where?  Random search (yep, I know, this is a stupid algorithm)  Serial search – O(n)  Binary search hunting a lion in the desert

Binary search The binary-search algorithm 1.If your list is of size 0, return “not-found”. 2.Check the item located in the middle of your list. 3.If this item is equal to the item you are looking for: you’re done! Return “found”. 4.If this item is bigger than the item you are looking for: do a binary-search on the first half of the list. 5.If this item is smaller than the item you are looking for: do a binary-search on the second half of the list. 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. ABC

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) ABC  What should the base case be?  Assuming each disk move takes 1 second, how long would it take to move a 64 disk tower?

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, preorder(node.left) preorder(node.right) preorder(root)

Traversing a phylogenetic tree def postorder(node): if node == None: return postorder(node.left) postorder(node.right) print node.value, postorder(root)  Recursion is extremely useful when processing a data structure that is recursive by nature. def preorder(node): if node == None: return print node.value, preorder(node.left) preorder(node.right) preorder(root)

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

helper function # Merge two sorted lists def merge(list1, list2): merged_list = [] i1 = 0 i2 = 0 # Merge while i1 < len(list1) and i2 < len(list2): if list1[i1] <= list2[i2]: merged_list.append(list1[ii]) i1 += 1 else: merged_list.append(list2[i2]) i2 += 1 # One list is done, move what's left 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 # merge sort recursive def sort_r(list): if len(list) > 1: # Still need to sort half_point = len(list)/2 first_half = list[:half_point] second_half = list[half_point:] first_half_sorted = sort_r(first_half) second_half_sorted = sort_r(second_half) sorted_list = merge \ (first_half_sorted, second_half_sorted) return sorted_list else: return list 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 List of size 1. Base case

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).  Recursion can be very costly!  Calling a function entails overhead  Overhead can be high when function calls are numerous (stack overflow)

Recursion vs. Iteration  Check the following two solutions for the Fibonacci sequence: # Returns the n-th Fibonacci number def fib_loop(n): prev = 0 curr = 1 for i in range(n-2): curr, prev = curr+prev, curr return curr # Returns the n-th Fibonacci number def fib_rec(n): if n == 1: return 0 elif n == 2: return 1 else: return fib_rec(n-1)+fib_rec(n-2) Which one would you prefer?

Recursion - the take home message  Recursion is a great tool to have in your problem- solving toolbox.  In many cases, recursion provides a natural and elegant solution to complex problems.  If the recursive version and the loop version are similar, prefer the loop version to avoid overhead.  Yet, even in these cases, recursion offers a creative way to think about how a problem could be solved.

Sample problem #1  Write a function that calculates the sum of the elements in a list using a recursion Hint: your code should not include ANY for-loop or while-loop!  Put your function in a module, import it into another code file and use it to sum the elements of some list.

def sum_recursive(a_list): if len(a_list) == 1: return a_list[0] else: return a_list[0] + sum_recursive(a_list[1:]) Solution #1 utils.py my_list = [1, 3, 5, 7, 9, 11] from utils import sum_recursive print sum_recursive(my_list) my_prog.py

Sample problem #2  Write a recursive function that determines whether a string is a palindrome. Again, make sure your code does not include any loops. A palindrome is a word or a sequence that can be read the same way in either direction. 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(" ") 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: Note: you can use a for loop to find a divisor of a number but the factorization process itself should be recursive! 2.Improve your function so that it “returns” a list containing the prime factors. Use pass-by-reference to return the list. 3.Can you do it without using ANY loops whatsoever? >>> prime_factorize(5624) >>> prime_factorize( )

import math def prime_factorize(number): # find the first divisor divisor = number for i in range(2,int(math.sqrt(number))+1): if number % i == 0: divisor = i break print divisor, if divisor == number: # number is prime. nothing more to do return else: # We found another divisor, continue prime_factorize(number/divisor) prime_factorize( ) Challenge solution 1

import math def prime_factorize(number, factors=[]): # find the first divisor divisor = number for i in range(2,int(math.sqrt(number))+1): if number % i == 0: divisor = i break factors.append(divisor) if divisor == number: # number is prime. nothing more to do return else: # We found another divisor, continue prime_factorize(number/divisor, factors) factors = [] prime_factorize( ,factors) print factors Challenge solution 2