* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Download Dynamic Programming
Survey
Document related concepts
Computational electromagnetics wikipedia , lookup
Inverse problem wikipedia , lookup
Algorithm characterizations wikipedia , lookup
Perturbation theory wikipedia , lookup
Genetic algorithm wikipedia , lookup
Simplex algorithm wikipedia , lookup
Mathematical optimization wikipedia , lookup
Knapsack problem wikipedia , lookup
Recursion (computer science) wikipedia , lookup
Computational complexity theory wikipedia , lookup
Dijkstra's algorithm wikipedia , lookup
Travelling salesman problem wikipedia , lookup
Multiple-criteria decision analysis wikipedia , lookup
Transcript
DESIGN & ANALYSIS OF ALGORITHM DYNAMIC PROGRAMMING Informatics Department Parahyangan Catholic University INTRODUCTION We have seen some algorithm design principles, such as divide-and-conquer, brute force, and greedy Brute force is widely applicable, but inefficient Divide-and-conquer and greedy are fast, but only applicable on very specific problems. Dynamic Programming is somewhere in between them, while still providing polynomial time complexity, it is widely applicable. DYNAMIC PROGRAMMING (DP) Similar to divide-and-conquer, DP solves problem by combining the solutions of its sub-problems. The term “programming” here refers to a tabular method DP solves a sub-problem, then saves its solution in a table FINDING N-TH FIBONACCI NUMBER F(n) = 0 1 F(n-1) + F(n-2) n=0 n=1 n>1 Recursive solution : FIBONACCI (n) if (n==0) return 0 else if (n==1) return 1 else return FIBONACCI(n-1) + FIBONACCI(n-2) FINDING N-TH FIBONACCI NUMBER Recursive solution : F(5) F(4) F(3) F(3) F(2) F(1) F(2) F(1) F(0) F(1) F(2) F(0) F(1) F(1) F(0) FINDING N-TH FIBONACCI NUMBER Memoization : Maintain a table to store sub-problem’s solution solution with memoization: // Initially : Arr[0] = 0 // Arr[1] = 1 // Arr[2..n] = -1 FIBONACCI (n) if (Arr[n] != -1) return Arr[n] else Arr[n]=FIBONACCI(n-1) + FIBONACCI(n-2) return Arr[n] FINDING N-TH FIBONACCI NUMBER solution with memoization: F(5) F(4) F(3) =2 F(2) =1 F(3) F(2) F(1) F(1) F(0) n 0 1 2 3 4 5 F(n) 0 1 -1 1 -1 2 -1 3 -1 5 FINDING N-TH FIBONACCI NUMBER Bottom-up solution : Use the natural ordering of sub-problems, solve them one-by-one starting from the “smallest” one Bottom-up solution: FIBONACCI (n) Arr[0] = 0 Arr[1] = 1 if(n>1) for i=2 to n do Arr[i] = Arr[i-1] + Arr[i-2] return Arr[n] TIME COMPLEXITY Recursive solution : FIBONACCI (n) if (n==0) return 0 else if (n==1) return 1 else return FIBONACCI(n-1) + FIBONACCI(n-2) Height = n F(n) F(n-1) F(n-2) F(n-3) Every instance has ≤ 2 recursive calls F(n-2) F(n-3) F(n-4) Therefore, time complexity is O(2n) TIME COMPLEXITY Bottom-up solution: FIBONACCI (n) Arr[0] = 0 Arr[1] = 1 if(n>1) for i=2 to n do Arr[i] = Arr[i-1] + Arr[i-2] return Arr[n] There is a loop that iterates ≤ n times, each doing a constant amount of work. So the time complexity is O(n) ROD CUTTING PROBLEM Serling Enterprises buys long steel rods and cuts them into shorter rods, which it then sells. Each cut is free, however different rod length sells for different price. The management of Sterling Enterprises wants to know the best way to cut up the rods. We assume that we know : length 1 2 3 4 5 6 7 8 9 10 price 1 5 8 9 10 17 17 20 24 30 Example : n=4 (n-1) possible cut locations 2n-1 ways of cutting ROD CUTTING PROBLEM length 1 2 3 4 5 6 7 8 9 10 price 1 5 8 9 10 17 17 20 24 30 Example : n=4 1 9 1 5 =7 =9 1 8 1 5 1 =9 BEST 5 =7 5 5 =10 8 1 1 =7 1 =9 1 1 1 1 =4 ROD CUTTING PROBLEM 1 i n Consider a rod of length n, and we cut a rod of length i Then we left with a rod of length n-i Naturally, we want to optimize the selling price of the remaining rod ROD CUTTING PROBLEM Recursive solution : ROD-CUTTING (n) if (n==0) return 0 else best = -∞ for i=1 to n do best = MAX(best, price[i]+ROD-CUTTING(n-i)) return best ROD CUTTING PROBLEM Recursive solution : RC(4) RC(2) RC(3) RC(2) RC(1) RC(0) RC(0) RC(1) RC(0) RC(0) RC(1) RC(0) RC(1) RC(0) RC(0) Same problem as recursive Fibonacci RC(0) ROD CUTTING PROBLEM Solution with memoization: // Initially : Arr[0] = 0 // Arr[1..n] = -∞ ROD-CUTTING (n) if Arr[n] ≥ 0 return Arr[n] else best = -∞ for i=1 to n do best = MAX(best, price[i]+ROD-CUTTING(n-i)) Arr[n] = best return best Exercise Write a bottom-up solution for Rod Cutting problem ! TIME COMPLEXITY Recursive solution : ROD-CUTTING (n) if (n==0) return 0 else best = -∞ for i=1 to n do best = MAX(best, price[i]+ROD-CUTTING(n-i)) return best Every instance has ≤ n recursive calls, and the depth of the recursive tree is O(n). So the time complexity is O(nn) What is the time complexity for the bottom-up solution ? SHORTEST PATH IN DAG DAG = Directed Acyclic Graph Example : 1 6 A B 1 4 S 2 C 2 3 D E 1 SHORTEST PATH IN DAG 6 A 1 B 1 4 S 2 2 3 C E 1 D Sort using topological sort 3 S 2 C 1 4 A 6 B 1 D 2 1 E SHORTEST PATH IN DAG Starting from S, suppose we want to reach node D The only way to reach D is either through B or C dist(D) = MIN(dist(B)+1 , dist(C)+3) 3 S 2 C 1 4 A 6 B 1 D 2 1 E SHORTEST PATH IN DAG A similar relation can be written for every node. As we have seen before, it is best to use bottom-up way of computing dist, that is from “left most” node to “right most” node DAG-SHORTEST-PATH () initialize all dist[.] to ∞ dist[S] = 0 for each vertex v except S in left-to-right order do for each edge (u,v) do dist[v] = MIN(dist[v] , dist[u] + weight(u,v)) DYNAMIC PROGRAMMING DAG’s shortest path is a very general technique. We model many other problems into DAG problem. Example #1: Fibonacci 0 1 0 1 2 3 4 3 4 Example #2 : Rod Cutting 0 0 1 2 5 PROPERTIES OF DYNAMIC PROGRAMMING Problem can be divided into smaller sub-problems Optimal substructure: an optimal solution to the problem contains within its optimal solutions to sub-problems Overlapping sub-problems: the space of sub-problems is “small”, in the sense that a recursive algorithm for the problem solves the same sub-problems over and over, rather than always generating new sub-problems DYNAMIC PROGRAMMING V.S. DIVIDE-AND-CONQUER Divide-and-Conquer Dynamic Programming And so on… LONGEST INCREASING SUBSEQUENCE Given a sequence of numbers a1, a2, a3, … , an. A subsequence is any subset of these numbers taken in order of the form ai1, ai2, ai3…, aik, where 1 ≤ i1 < i2 < … < ik ≤ n, and an increasing subsequence is one which the numbers are getting strictly larger. The task is to find the increasing subsequence of greatest length. Example: 5, 2, 8, 6, 3, 6, 9, 7 LONGEST INCREASING SUBSEQUENCE How do we model this problem into a DAG ? any number ai can precede aj iff ai < aj 5 2 8 6 3 Consider this number, LIS that ends here must be either: • subsequence consist of “6” alone • LIS that ends at “5” + “6” • LIS that ends at “2” + “6” • LIS that ends at “”3” + “6” 6 9 7 LONGEST INCREASING SUBSEQUENCE How do we find the LIS of sequence 5, 2, 8, 6, 3, 6, 9, 7 ? Does the optimal solution always ends at “7” ? // Initially L[1..n] = 1 LONGEST-INCREASING-SUBSEQUENCE () for j=2 to n do for each i<j such that ai < aj do if(L[j] < 1 + L[i]) then L[j] = 1 + L[i] return maximum of L[1..n] This algorithm only gives the sequence’s length. How do we find the actual sequence ? RECONSTRUCTING A SOLUTION We can extend the dynamic programming approach to record not only the optimal value for each sub-problem, but also the choice that led to that value // Initially L[1..n] = 1 // Initially prev[1..n] = 0 LONGEST-INCREASING-SUBSEQUENCE () for j=2 to n do for each i<j such that ai < aj do if(L[j] < 1 + L[i]) then L[j] = 1 + L[i] prev[j] = i return maximum of L[1..n] and array prev EXERCISE : YUCKDONALD’S Yuckdonald’s is considering opening a series of restaurants along Quaint Valley Highway (QVH). The n possible locations are along a straight line, and the distance of these locations from the start of QVH are, in miles and in increasing order, m1, m2, …, mn. The constraints are as follows: At each location, Yuckdonald’s may open at most one restaurant. The expected profit from opening a restaurant at location i is pi > 0 Any two restaurants should be at least k miles apart, where k is a positive integer