Recursion & Dynamic Programming. Algorithm Design & Software Engineering March 17, 2016 Stefan Feuerriegel

Similar documents
Algorithm classification

PROGRAM EFFICIENCY & COMPLEXITY ANALYSIS

asymptotic growth rate or order compare two functions, but ignore constant factors, small inputs

L.J. Institute of Engineering & Technology Semester: VIII (2016)

CS 506, Sect 002 Homework 5 Dr. David Nassimi Foundations of CS Due: Week 11, Mon. Apr. 7 Spring 2014

CS 137 Part 7. Big-Oh Notation, Linear Searching and Basic Sorting Algorithms. November 10th, 2017

DESIGN AND ANALYSIS OF ALGORITHMS

Algorithm Analysis and Design

Scientific Computing. Algorithm Analysis

CSE373: Data Structure & Algorithms Lecture 21: More Comparison Sorting. Aaron Bauer Winter 2014

Unit-5 Dynamic Programming 2016

LECTURE NOTES OF ALGORITHMS: DESIGN TECHNIQUES AND ANALYSIS

Sankalchand Patel College of Engineering - Visnagar Department of Computer Engineering and Information Technology. Assignment

Introduction to Algorithms / Algorithms I Lecturer: Michael Dinitz Topic: Dynamic Programming I Date: 10/6/16

CSE373: Data Structures and Algorithms Lecture 4: Asymptotic Analysis. Aaron Bauer Winter 2014

DIVIDE & CONQUER. Problem of size n. Solution to sub problem 1

10/5/2016. Comparing Algorithms. Analyzing Code ( worst case ) Example. Analyzing Code. Binary Search. Linear Search

Algorithms in Systems Engineering IE172. Midterm Review. Dr. Ted Ralphs

Elementary maths for GMT. Algorithm analysis Part I

CS126 Final Exam Review

Run Times. Efficiency Issues. Run Times cont d. More on O( ) notation

Dynamic Programming. An Introduction to DP

Lecture #2. 1 Overview. 2 Worst-Case Analysis vs. Average Case Analysis. 3 Divide-and-Conquer Design Paradigm. 4 Quicksort. 4.

UNIT 1 ANALYSIS OF ALGORITHMS

CSci 231 Final Review

Analysis of Algorithms. CSE Data Structures April 10, 2002

Introduction to Computer Science

Elements of Dynamic Programming. COSC 3101A - Design and Analysis of Algorithms 8. Discovering Optimal Substructure. Optimal Substructure - Examples

Mergesort again. 1. Split the list into two equal parts

Measuring algorithm efficiency

Chapter 3, Algorithms Algorithms

Plotting run-time graphically. Plotting run-time graphically. CS241 Algorithmics - week 1 review. Prefix Averages - Algorithm #1

Lecture 19 Sorting Goodrich, Tamassia

Chapter 3:- Divide and Conquer. Compiled By:- Sanjay Patel Assistant Professor, SVBIT.

Computational Complexity: Measuring the Efficiency of Algorithms

Algorithm Design Techniques part I

Basic Data Structures (Version 7) Name:

CITS3001. Algorithms, Agents and Artificial Intelligence. Semester 2, 2016

Design and Analysis of Algorithms Prof. Madhavan Mukund Chennai Mathematical Institute. Module 02 Lecture - 45 Memoization

Day 10. COMP1006/1406 Summer M. Jason Hinek Carleton University

CSC Design and Analysis of Algorithms. Lecture 5. Decrease and Conquer Algorithm Design Technique. Decrease-and-Conquer

Adam Blank Lecture 2 Winter 2017 CSE 332. Data Structures and Parallelism

CMSC 451: Lecture 10 Dynamic Programming: Weighted Interval Scheduling Tuesday, Oct 3, 2017

Algorithms and Data Structures

So far... Finished looking at lower bounds and linear sorts.

Computer Algorithms CISC4080 CIS, Fordham Univ. Instructor: X. Zhang Lecture 1

Computer Algorithms CISC4080 CIS, Fordham Univ. Acknowledgement. Outline. Instructor: X. Zhang Lecture 1

Algorithmics. Some information. Programming details: Ruby desuka?

Dynamic Programming. Introduction, Weighted Interval Scheduling, Knapsack. Tyler Moore. Lecture 15/16

17/05/2018. Outline. Outline. Divide and Conquer. Control Abstraction for Divide &Conquer. Outline. Module 2: Divide and Conquer

Lecturers: Sanjam Garg and Prasad Raghavendra March 20, Midterm 2 Solutions

Data Structures and Algorithms

CLASS: II YEAR / IV SEMESTER CSE CS 6402-DESIGN AND ANALYSIS OF ALGORITHM UNIT I INTRODUCTION

3. Java - Language Constructs I

Lecture 5: Running Time Evaluation

Algorithmic Analysis. Go go Big O(h)!

Outline and Reading. Analysis of Algorithms 1

Framework for Design of Dynamic Programming Algorithms

11. Divide and Conquer

Algorithm Analysis. (Algorithm Analysis ) Data Structures and Programming Spring / 48

Algorithms for Data Science

Agenda. The worst algorithm in the history of humanity. Asymptotic notations: Big-O, Big-Omega, Theta. An iterative solution

COE428 Lecture Notes Week 1 (Week of January 9, 2017)

Algorithm Efficiency & Sorting. Algorithm efficiency Big-O notation Searching algorithms Sorting algorithms

1 Format. 2 Topics Covered. 2.1 Minimal Spanning Trees. 2.2 Union Find. 2.3 Greedy. CS 124 Quiz 2 Review 3/25/18

Data Structures, Algorithms & Data Science Platforms

Chapter 3 Dynamic programming

Selection (deterministic & randomized): finding the median in linear time

Analysis of Algorithms

What is an Algorithm?

CS6402-DESIGN AND ANALYSIS OF ALGORITHM. TWO MARK QUESTION WITH ANSWERS Unit-I. Introduction

CSE 373 MAY 24 TH ANALYSIS AND NON- COMPARISON SORTING

Algorithms and Programming

CSC 505, Spring 2005 Week 6 Lectures page 1 of 9

CMPSCI 187: Programming With Data Structures. Lecture 5: Analysis of Algorithms Overview 16 September 2011

Virtual University of Pakistan

The divide-and-conquer paradigm involves three steps at each level of the recursion: Divide the problem into a number of subproblems.

Lecture 2: Algorithm Analysis

Scribe: Sam Keller (2015), Seth Hildick-Smith (2016), G. Valiant (2017) Date: January 25, 2017

SAMPLE OF THE STUDY MATERIAL PART OF CHAPTER 6. Sorting Algorithms

Sorting & Growth of Functions

Algorithm Analysis. College of Computing & Information Technology King Abdulaziz University. CPCS-204 Data Structures I

Midterm solutions. n f 3 (n) = 3

CS583 Lecture 01. Jana Kosecka. some materials here are based on Profs. E. Demaine, D. Luebke A.Shehu, J-M. Lien and Prof. Wang s past lecture notes

Pseudo code of algorithms are to be read by.

The divide and conquer strategy has three basic parts. For a given problem of size n,

Visualizing Data Structures. Dan Petrisko

The Running Time of Programs

Algorithms in Systems Engineering ISE 172. Lecture 12. Dr. Ted Ralphs

Introduction to Algorithms

Problem. Input: An array A = (A[1],..., A[n]) with length n. Output: a permutation A of A, that is sorted: A [i] A [j] for all. 1 i j n.

/633 Introduction to Algorithms Lecturer: Michael Dinitz Topic: Sorting lower bound and Linear-time sorting Date: 9/19/17

Programming II (CS300)

MUHAMMAD FAISAL MIT 4 th Semester Al-Barq Campus (VGJW01) Gujranwala

Lecture 2: Getting Started

CS 173, Running Time Analysis, Counting, and Dynamic Programming. Tandy Warnow

CSCE 411 Design and Analysis of Algorithms

Analysis of Algorithms. Unit 4 - Analysis of well known Algorithms

Today s Outline. CSE 326: Data Structures Asymptotic Analysis. Analyzing Algorithms. Analyzing Algorithms: Why Bother? Hannah Takes a Break

Data Structures Lecture 8

Transcription:

Recursion & Dynamic Programming Algorithm Design & Software Engineering March 17, 2016 Stefan Feuerriegel

Today s Lecture Objectives 1 Specifying the complexity of algorithms with the big O notation 2 Understanding the principles of recursion and divide & conquer 3 Learning the contrary concept of dynamic programming Recursion & DP 2

Outline 1 Computational Complexity 2 Recursion 3 Dynamic Programming 4 Greedy Algorithms Recursion & DP 3

Outline 1 Computational Complexity 2 Recursion 3 Dynamic Programming 4 Greedy Algorithms Recursion & DP: Computational Complexity 4

Need for Efficient Algorithms Computers can perform billions of arithmetic operations per second, but this might not be sufficient Memory is also limited Need for efficient algorithms that scale well Runtime T(n) 400 300 200 100 0 2 4 6 Problem Size n Exponential Growth Quadratic Growth Examples Go games last up to 400 moves, with around 250 choices per move Cracking a 2048 bit RSA key theoretically requires 2 112 trials Calculating the optimal order of delivering n parcels has n! possibilities Recursion & DP: Computational Complexity 5

Computational Complexity Computational complexity is measured by time T (n) and space S(n) Exact measurements (e. g. timings) have shortcomings Dependent on specific hardware setup Difficult to convert into timings for other architectures Cannot describe how well the algorithm scales Initialization times are usually neglected Approach Count operations as a function of problem size n Analyze best-case, average and worst-case behavior Recursion & DP: Computational Complexity 6

Computational Complexity Question What is the default number of operations for x 2 = x T x for x R n? 1 square root, 1 multiplication 1 square root, n multiplications and n 1 additions 1 square root, n multiplications and n additions No Pingo available Question What better upper bound can one achieve for summing over n numbers? n 1 additions n/2 additions log n additions No Pingo available Recursion & DP: Computational Complexity 7

Big O Notation Big O notation (or Landau O) describes the asymptotic or limiting behavior What happens when input parameters become very, very large Groups functions with the same growth rate (or an upper bound of that) Common functions Notation Name Example O(1) Constant Test if number is odd/even O(log n) Logarithmic Finding an item in a sorted list O(n log n) Loglinear Sorting n numbers O(n) Linear Dot product, finding an item in an unsorted list O(n 2 ) Quadratic Default matrix-by-vector multiplication O(n c ) Polynomial Default matrix-by-matrix multiplication O(c n ) Exponential Traveling salesman problem with DP Recursion & DP: Computational Complexity 8

Big O Notation Example: testing if a number n is prime can be in O(n) or O( n) 1 Variant in O(n) Iterate all numbers in the range i = 2,...,n and check if i is an integer divisor of n for (i in 2:n) { if (n%%i == 0) { print("not prime") 2 Variant in O( n) Changing for-loop as the largest possible divisor is n for (i in 2:sqrt(n)) { if (n%%i == 0) { print("not prime") Recursion & DP: Computational Complexity 9

Complexity Classes Even small cases are intractable for inefficient algorithms 1 10 +7 1 10 +5 1 10 +3 1 10 +1 n^n n! 2^n n^2 n log n log n 1 2 4 6 8 Problem Size n Recursion & DP: Computational Complexity 10

Big O Notation Classifies algorithms by how they respond (e. g. in their runtime) to changes in input size Gives the worst-case complexity regarding time or space Let f,g : N R +, we define f(x) = O(g(x)) as x if and only if f(x) c g(x) x x 0 where c is a positive constant Mathematically correct is f(x) O(g(x)), though more common is f = O(g) where = means is Recursion & DP: Computational Complexity 11

Big O Notation Example Assume f(x) = 5x 2 + 10x + 20 5x 2 is the highest growth rate To prove f(x) = O(g(x)) with g(x) = x 2, let x 0 = 1 and c = 35 f(x) c g(x) 5x 2 + 10x + 20 5x 2 + 10x + 20 5x 2 + 10x + 20 5x 2 + 10x 2 + 20x 2 5x 2 + 10x + 20 35x 2 10x + 20 30x 2 Hence f(x) = 5x 2 + 10x + 20 = O(x 2 ) Recursion & DP: Computational Complexity 12

O Calculus Multiplication by a constant Let c 0 be a constant, then O(c g) = O(g) e. g.changing the underlying hardware does not affect the complexity Example: 5 O(1) = O(1) Sum rule Let f 1 = O(g 1 ) and f 2 = O(g 2 ), then f 1 + f 2 = O(g 1 + g 2 ) e. g. complexity of sequentially executing two algorithms is only affected by the one with the higher complexity As a special case: f 1 = O(g) and f 2 = O(g) f 1 + f 2 = O(g) Example: O(x) + O(x 2 ) = O(x 2 ) Product rule Assume f 1 = O(g 1 ) and f 2 = O(g 2 ), then f 1 f 2 = O(g 1 g 2 ) e. g. matches nested execution of loops Recursion & DP: Computational Complexity 13

Big O Notation The complexity class is a set of functions defined by O(g) = {f : N R + x 0 N,c R,c > 0 x x 0 : f(x) c g(x) Alternative to prove f = O(g) is to show that the following limits exists Example f(x) lim x g(x) < Show f(x) = 5x 2 + 10x + 20 = O(x 2 ) Apply limit theory f(x) 5x 2 + 10x + 20 lim = x x 2 lim = x x 2 5 < Recursion & DP: Computational Complexity 14

Related Notations Different variants exists for all forms of lower and upper bounds, e. g. 1 Upper bound f = O(g): f grows not faster than g 2 Lower bound f = Ω(g): f grows at least as quickly as g 3 Tight bound f = Θ(g): f and g grow at the same rate If f = Ω(g) and f = O(g), then f = Θ(g) because 1 c 1 f(x) {{ =Ω(g) f(x) {{ =Θ(f) c g(x) c 2 f(x) {{ =O(g) x x 0 3 c 2 g(x) f(x) f(x) c 1 g(x) x 0 x x 0 x Recursion & DP: Computational Complexity 15

Outline 1 Computational Complexity 2 Recursion 3 Dynamic Programming 4 Greedy Algorithms Recursion & DP: Recursion 16

Recursion Idea Design algorithm to solve a problem by progressively solving smaller instances of the same problem Definition Recursion is a process in which a function calls itself with: 1 a base case which terminates the recursion Producing an answer without a recursive call 2 a set of rules which define how a base case is finally reached Pseudocode recursion <- function(...) { if (condition) { return(base_case) return(recursion(...)) # recursive call Recursion & DP: Recursion 17

Factorial Factorial is the product of all positive numbers less or equal n Example: 5! = 5 i = 1 2 3 4 5 = 120 i=1 Recurrence equation { 1 if n = 1 n! := n (n 1)! if n 2 Number of function calls is Θ(n) fact <- function(n) { if (n == 0) { return(1) return(n * fact(n-1)) fact(5) ## [1] 120 Recursion & DP: Recursion 18

Fibonacci Numbers Fibonacci sequence of integers F n for n N Recurrence equation F n := F n 1 + F n 2 for n 3 Base cases F 1 := 1 and F 2 := 1 Example F 5 Call stack for n = 5 =F 4 + F 3 =F 3 + F {{ 2 +F 2 + F {{ 1 =F 4 =F 3 =F 2 + F 1 {{ =F 3 +F 2 + F 2 + F 1 =1 + 1 + 1 + 1 + 1 =5 fib(2) = 1 fib(5) = 5 fib(4) = 3 fib(3) = 2 fib(3) = 2 fib(2) = 1 fib(2) = 1 fib(1) = 1 + + fib(1) = 1 + + Recursion & DP: Recursion 19

Fibonacci Numbers Implementation fibonacci <- function(n) { # base case if (n == 1 n == 2) { return(1) # recursive calls return(fibonacci(n-1) + fibonacci(n-2)) Example fibonacci(5) ## [1] 5 Recursion & DP: Recursion 20

Computational Complexity Superlinear growth in the number of function calls Total Function Calls 10000 5000 0 5 10 15 20 n Number of function calls is in O(F n ) = O(c n ) But there are more efficient approaches, such as dynamic programming or a closed-form formula Recursion & DP: Recursion 21

Divide and Conquer Divide and conquer (D&C) is an algorithm pattern based on recursion 1 Divide complex problem into smaller, non-overlapping sub-problems 2 Conquer, i. e. find optimal solution to these sub-problems recursively 3 Combine solutions to solve the bigger problem Problem Divide Sub-problem 1... Sub-problem n Common tasks Sorting Conquer Combine Solution to sub-problem 1... Solution to sub-problem n Computational geometry MapReduce in Hadoop Solution to problem Recursion & DP: Recursion 22

Quicksort Quicksort is an efficient sorting algorithm for sorting x R n Average performance is O(n logn), worst-case O(n 2 ) Idea 1 Choose pivot element from vector x 2 Partitioning: split into two parts x i < pivot and x i pivot 3 Recursively apply to each part (and combine) Example 4 2 3 1 < pivot pivot 2 1 4 3 < pivot pivot < pivot pivot 1 2 3 4 Recursion & DP: Recursion 23

Quicksort Function quicksort based on divide and conquer quicksort <- function(x) { # base case if (length(x) <= 1) { return(x) # pick random pivot element for "divide" pivot <- x[sample(length(x), 1)] # recursive "conquer" return(c(quicksort(x[x < pivot]), quicksort(x[x >= pivot]))) Example # "left" # "right" quicksort(c(4, 2, 3, 1)) ## [1] 1 2 3 4 Recursion & DP: Recursion 24

Mergesort Idea 1 Divide vector into sub-vectors until you have vectors of length 1 2 Conquer by merging sub-vectors recursively (i. e. fill in right order) 4 2 3 1 Divide 4 2 3 1 1 2 3 4 Conquer 2 4 1 3 Divide Divide Conquer Conquer 4 2 3 1 4 2 3 1 Average and worst-case performance are in O(n log n) but with higher factor in practice Recursion & DP: Recursion 25

Mergesort 1 Divide operation to split vector and then merge mergesort <- function(x) { if (length(x) == 1) { return(x) # divide recursively split <- ceiling(length(x)/2) u <- mergesort(x[1:split]) v <- mergesort(x[(split+1):length(x)]) # call conquer step return(merge(u, v)) Recursion & DP: Recursion 26

Mergesort 2 Conquer operation which merges two vectors recursively merge <- function(u, v) { # input u and v must be sorted # new empty vector x.sorted <- numeric(length(u) + length(v)) # indices pointing to element processed next uj <- 1 vj <- 1 for (i in 1:length(x.sorted)) { # case 1: v is completely processed => take u # case 2: still elements in u and the next # u element is smaller than the one in v if (vj > length(v) (uj <= length(u) && u[uj] < v[vj])) { x.sorted[i] <- u[uj] uj <- uj + 1 else { # Otherwise: take v x.sorted[i] <- v[vj] vj <- vj + 1 return(x.sorted) # return sorted vector Recursion & DP: Recursion 27

Mergesort Example of merging two vectors as part of conquer step merge(4, 2) ## [1] 2 4 merge(c(2, 4), c(1, 3)) ## [1] 1 2 3 4 Example of mergesort mergesort(4) ## [1] 4 mergesort(c(4, 2)) ## [1] 2 4 mergesort(c(4, 2, 3, 1)) ## [1] 1 2 3 4 Recursion & DP: Recursion 28

Outline 1 Computational Complexity 2 Recursion 3 Dynamic Programming 4 Greedy Algorithms Recursion & DP: Dynamic Programming 29

Dynamic Programming Idea Dynamic programming (DP) uses a memory-based data structure Reuse previous results Speed-ups computation but at the cost of increasing memory space Approach Divide a complex problem into smaller, overlapping sub-problems Find optimal solution to these sub-problems and remember them Combine solutions to solve the bigger problem All sub-problems are ideally solved exactly once Implementation Sub-problems can be processed in top-down or bottom-up order Bottom-up DP is usually faster by a constant factor Recursion & DP: Dynamic Programming 30

Dynamic Programming Example: Fibonacci numbers Recursive approach triggers many redundant function calls Reordering these function calls can improve the performance Dependencies in recursion Dependencies in DP F 5 F 5 F 4 F 3 F 4 F 3 F 3 F 2 F 2 F 1 F 2 F 1 F 2 F 1 Recursion & DP: Dynamic Programming 31

Dynamic Programming Top-down approach: memoization Store solutions to sub-problems in a table that is build top-down For each sub-problem, check table first if there is already a solution 1 If so, reuse it 2 If not, solve sub-problem and add solution to table Bottom-up approach: tabulation Store solutions to sub-problems in a table that is build bottom-up Start with the smallest sub-problem Solve sub-problem and store solution Use solutions of smaller sub-problems to solve bigger ones Recursion & DP: Dynamic Programming 32

Comparison Example: Fibonacci numbers with top-down dynamic programming Top-down DP Bottom-up DP F N F N 1 F N 2 F N F N 1 F N 2 F N 3 F N 2 F 2 F 1 F 1 Recursion & DP: Dynamic Programming 33

Top-Down DP fib_topdown <- function(n) { # check cache first if (!is.na(memo_table[n])) { return(memo_table[n]) # solve sub-problem if (n == 1 n == 2) { F <- 1 else { F <- fib_topdown(n-1) + fib_topdown(n-2) memo_table[n] <<- F return(f) # add solution to global table Operator <<- sets a global variable outside the function Recursion & DP: Dynamic Programming 34

Top-Down DP Set up example n = 5 n <- 5 Create global memoization table memo_table <- rep(na, n) Run top-down algorithm fib_topdown(n) ## [1] 5 View memoization table after execution memo_table ## [1] 1 1 2 3 5 Recursion & DP: Dynamic Programming 35

Bottom-Up DP Example: Fibonacci numbers with bottom-up dynamic programming fib_bottomup <- function(n) { # initialization of table fib <- numeric(n) fib[1] <- 1 fib[2] <- 1 # bottom-up construction for (i in 3:n) { fib[i] <- fib[i-1] + fib[i-2] return(fib[n]) fib_bottomup(5) ## [1] 5 Recursion & DP: Dynamic Programming 36

Comparison: Fibonacci Numbers Recursion Runtime O(c n ) becomes infeasible even for small n Direct space is O(1) but the call stack needs O(n) Top-down DP Runtime O(n) Space O(n) and additional call stack in O(n) Bottom-up DP Runtime O(n) Space O(n) and no call stack Storing only last two values can reduce it to O(1) Recursion & DP: Dynamic Programming 37

Knapsack Problem Description Suppose you want to steal items from a shop Each item i has weight w i and price p i Which items to choose? Optimization Problem Decision variable x i {0,1 tells whether to include item i Your aim is to maximize your profit P = max x 1,...,x n n i=1 x i w i Limitation is the capacity W of your bag n i=1 x i w i W Recursion & DP: Dynamic Programming 38

Knapsack Problem Example Load necessary library library(adagio) Sample values w <- c(2, 4, 5, 7, 9) p <- c(1, 5, 4, 10, 20) W <- 13 Solve problem with dynamic programming knapsack <- knapsack(w, p, W) knapsack$profit # maximum possible profit ## [1] 25 Print decision variable, i. e. which items to choose knapsack$indices ## [1] 2 5 Recursion & DP: Dynamic Programming 39

DP for Knapsack Problem Build up matrix M i,j for i = 0,...,n and j = 0,...,W M i,j is the maximum profit with items 1,...,i and weight of up to j Solution to knapsack problem is given by M n,w Recursive definition of M 0 if i = 0 M i,j := M i 1,j if w i > j max{m i 1,j,M i 1,j wi + p i if w i j The reasons behind the cases are 1 If i = 0, the set of items is empty 2 If w i > j, the new item exceeds the current weight limit j 3 Choose between Recursion & DP: Dynamic Programming Current-best solution without item i Combining price p i from item i and the recursive solution for the remaining, available weight j w i 40

Knapsack Problem Bottom-up DP needs runtime O(n W) and space O(n W) n <- length(p) # total number of items M <- matrix(0, nrow=n+1, ncol=w+1) # note: matrix indexing starts with 1 in R for (i in 1:n) { for (j in 0:W) { if (w[i] > j) { M[i+1, j+1] <- M[i, j+1] else { M[i+1, j+1] <- max(m[i, j+1], M[i, j-w[i]+1] + p[i]) M[n+1, W+1] ## [1] 25 Recursion & DP: Dynamic Programming 41

Bellman s Principle of Optimality Theoretical basis why DP works We find an optimal solution by solving each sub-problem optimally An optimal policy has the property that whatever the initial state and initial decision are, the remaining decisions must constitute an optimal policy with regard to the state resulting from the first decision Bellman (1957), Chap. 3 Such a problem is said to have a optimal sub-structure Greedy algorithms also produce good results Proof via backward induction Also highly relevant in game theory and reinforcement learning Recursion & DP: Dynamic Programming 42

Bellman s Principle of Optimality Problem Let s assume an optimization problem with t = 1,...,T steps Payoff F(t,a t ) in step t given decision a t ( action ) V(t) is the optimal total utility when starting in step t Calculated by maximizing V(1) = max Bellman equation T a 1,...,a T F(t,a t ) t=1 Separate today s decision a 1 from future decisions a 2,...,a T We can rewrite V(1) in a recursive fashion V(1) = max[f(1,a 1 ) + V(2)] a 1 Recursion & DP: Dynamic Programming 43

Outline 1 Computational Complexity 2 Recursion 3 Dynamic Programming 4 Greedy Algorithms Recursion & DP: Greedy Algorithms 44

Greedy Algorithms Idea Make locally optimal choices with the hope of finding global optimum Depending on problem, greedy algorithms can find optimum or only work as heuristic This depends on the specific setting optimal sub-structure Examples Decision tree learning Routing in networks Heuristics for complex optimization problems Recursion & DP: Greedy Algorithms 45

Greedy Algorithms Change-Making Problem What is the minimum number of coins when giving change? Assume that there is an infinite amount available Greedy strategy is to give out largest coins first and then continue in decreasing order Example: given 47 cents 47 20 = 27 20 27 20 = 7 20 20 Skip 10 7 5 = 2 20 20 5 2 2 = 0 20 20 5 2 Recursion & DP: Greedy Algorithms 46

Greedy Algorithm for Change-Making Problem min_coins_change <- function(cents) { # list of available coins coins <- c(200, 100, 50, 20, 10, 5, 2, 1) num <- 0 while (cents > 0) { if (cents >= coins[1]) { num <- num + 1 # one more coins cents <- cents - coins[1] # decrease remaining value else { # switch to next smaller coin coins <- coins[-1] # remove first entry in list return(num) min_coins_change(47) # 2x 20ct, 1x 5ct, 1x 2ct ## [1] 4 Recursion & DP: Greedy Algorithms 47

Heuristics Idea Find an approximate solution instead of the exact solution Usually used when direct method is not efficient enough Trade-off: optimality vs. runtime Common applications: logistics, routing, malware scanners Recursion & DP: Greedy Algorithms 48

Heuristic for Knapsack Problem Solve Knapsack problem by choosing items in the order of their price-to-weight ratio Greedy algorithm 1 Sort items by p i w i in decreasing order 2 Pick items in that order as long as capacity constraint remains fulfilled Runtime O(n) and space O(1) When number of items is unbounded (x i 0), the heuristic is only worse by fixed factor Heuristic always gives at least P /2 Recursion & DP: Greedy Algorithms 49

Heuristic for Knapsack Problem # generate greedy order according to price/weight ratio greedy_order <- order(p/w, decreasing=true) sum_p <- 0 # total profit in current iteration sum_w <- 0 # total weight in current iteration for (i in greedy_order) { if (sum_w + w[i] <= W) { sum_p <- sum_p + p[i] sum_w <- sum_w + w[i] sum_p # optimal solution was 25 ## [1] 25 Recursion & DP: Greedy Algorithms 50

Greedy Algorithms vs. Heuristics Greedy algorithms might fail to find the optimal solution This depends on the specific setting ( optimal sub-structure) Sometimes one can derive upper bounds Example Task is to find the path with the highest total sum Greedy approach achieves 11, while optimum is 114 8 8 7 2 7 2 99 3 0 1 99 3 0 1 Greedy solution Optimum solution Recursion & DP: Greedy Algorithms 51

Summary Computational complexity Even fast hardware needs efficient algorithms Algorithmic performance is measured by runtime and memory Asymptotic complexity is given by e. g. the big O notation (upper limit) Recursion Progressively solves smaller instances of a problem Function calls itself multiple times until reaching a base case Specific pattern is the approach of divide and conquer Recursion & DP: Wrap-Up 52

Summary Dynamic programming Dynamic programming can be top-down or bottom-up Stores solutions of sub-problems and reuses them Decreases runtime at the cost of increasing memory usage Greedy algorithms Making locally optimal choices to find or approximate global optimum Heuristics find approximate instead of exact solution Trade-off: solution quality vs. runtime Recursion & DP: Wrap-Up 53