Algorithm beauty: Dynamic Planning

Source: Internet
Author: User

Preface

As with the Division and Control Law, dynamic planning solves the entire problem by combining subproblems. Note that the programing translation here sets up a plan rather than programming. Wrote on Wikipedia

This is also usually done in a tabular form by iteratively generating solutions to bigger and bigger subproblems by using the solutions to small subproblems.

This shows that the key to dynamic regulation is table, which is a sub-problem. In addition, sub-Problems of motion planning are interrelated. The divide and conquer algorithm divides the problem into relatively independent sub-problems and recursively solves all sub-problems,

Then merge the sub-questions into the final result. In this process, the divide and conquer method will do a lot of unnecessary work, that is, repeatedly solving public subproblems.

The motion rule solves each subproblem once and saves the result in the table, thus avoiding repeated calculation of the subproblem.

Applicability

1. Dynamic Planning is usually applied to optimization problems. There are usually many feasible solutions for such problems. Each solution has a value, and we hope to find the optimal answer.

2. The problem must be ineffective. That is, the current State is a complete summary of history, and the evolution of the process is no longer affected by previous states and decisions.

Simple Dynamic Planning



Maximum sub-array and Problems

Question

One hasNAn array of integer elements (a [0], a [1],..., A [n-1], a [n]). Of course, this array has many subarrays. What is the maximum value of the sum of arrays?

This is a very simple question, but to write out the optimal method with the time complexity of O (N), we still need to elaborate carefully.

For example, an array of int A [5] = {-1, 2, 3,-4, 2 };

The matching sub-array is 2 and 3, that is, the answer is 5;

Clarify the meaning of the question

1. The sub-array must be continuous.

2. You do not need to return the specific position of the sub-array.

3. the array contains positive integers, zero integers, and negative integers.

For example

Array: {1,-2, 3, 5,-3, 2} The returned value is 8.

Array: {0,-2, 3, 5,-1, 2} returned value is 9

Array: {-9,-2,-3,-5,-6} The returned value is-2. Note that the sub-array cannot be empty.

First, let's look at the most direct method.

Int maxsubstring (int * a, int N) {int max = min; // The initial value is negative infinity int sum; For (INT I = 0; I <n; I ++) {sum = 0; For (Int J = I; j <n; j ++) {sum + = A [J]; If (sum> MAX) max = sum ;}} return Max ;}

This method is the most direct and time-consuming. Its time complexity is O (n ^ 2 );

Problem Analysis

Can it be optimized? The answer is yes. You can consider the first element of the array and the largest array (A [I],..., the relationship between a [J] And a [0] has the following situations:

1. When 0 = I = J, element a [0] itself constitutes and is the largest segment;

2. When 0 = I <J, and the maximum segment starts with a [0;

3. When 0 <I, element a [0] has no relationship with the largest segment.

We can see from the above 3. You can convert a big problem (N element arrays) into a smaller problem (an array of N-1 elements ). Suppose we already know that the sum of the largest array in (a [1],..., a [n-1]) and all [1], and we already know

(A [1],..., a [n-1]) contains a [1] and the largest array of start [1]. It is not difficult to see (a [0],..., solution to the problem in a [n]) All [0] = max {A [0], a [0] + start [1], all [1]}. Through this analysis, we can see this problem

It is ineffective and can be solved through dynamic planning.

Solution

Int maxsubstring (int * a, int N) {int start = A [n-1]; int all = A [n-1]; for (INT I = N-2; i> = 0; I --) // traverse forward from the back, and vice versa. {Start = max (A [I], a [I] + start); All = max (start, all);} return all [0]; // store results in all [0}

It is not only very efficient (time complexity is O (n) to solve this problem through the dynamic algorithm, but also extremely simple.




01 backpack Problems

Question

This topic is very famous, as long as it is a computer professional, you should have heard of it. There are n items and a backpack with a capacity of v. The volume of the I-th item is C [I], and the value is V [I]. Solving which items are loaded into a backpack can maximize the total value.

We have five items under the specific question. The size of the backpack is 10, and their volume is C [5] = {, 4 }; value: V [5] = {2, 4, 1, 6, 5 };


Problem Analysis

This is the most basic problem with a backpack. It features that each item has only one item, and you can choose to put it or not. The solution to the knapsack problem can be considered as a series of decision-making processes, that is, to decide which items should be put into the backpack and which will not be put into the backpack.

If the optimal solution for a problem contains item n, that is, xn = 1, then the remaining x1, x2 ,....., xn-1 must constitute a sub-problem 1, 2 ,....., n-1-1 Optimal Solution for capacity C-CN. If this optimal solution does not contain item n, that is, xn = 0;

Then the remaining X1, x2.... Xn-1 must constitute the subproblem 1, 2,... n-1 in capacity C optimal solution. // Please taste these words carefully

According to the above analysis of the optimal solution structure recursive definition of the problem of the optimal solution f [I] [v] = max {f [I-1] [v], f [I-1] [V-C [I] + V [I]}

Solution

# Include <iostream> # define max (A, B) (a)> (B )? A: B) int C [5] = {, 4}; int V [5] = {, 5 }; int f [6] [10] = {0}; // F [I] [v] = max {f [I-1] [v], f [I-1] [V-C [I] + W [I]} int main () {for (INT I = 1; I <6; I ++) for (Int J = 1; j <10; j ++) {If (C [I]> J) // if the size of the backpack is insufficient for C [I], c [I] f [I] [J] = f [I-1] [J]; else {f [I] [J] = max (F [I-1] [J], F [I-1] [J-C [I] + V [I]); // transfer equation} STD: cout <F [5] [9]; return 0 ;}

01 the knapsack problem is the most basic dynamic planning problem. It is also the most classic and easy to understand. Therefore, read this code carefully. It contains the most basic concepts of design states and equations in the knapsack problem.



Matrix concatenation

Question

Given n matrices {A1, A2,..., an}, where Ai and AI + 1 are multiplication, I =,... n-1. Consider the product of the N matrices. Because the competition multiplication satisfies the combination Law, the concatenation of the calculation matrix has many different calculation orders.

This calculation order can be determined by brackets. If the calculation order of a matrix concatenation is completely determined, this means that the concatenation is fully enclosed by brackets.

For example, matrix concatenation A1 * A2 * A3 * A4 can have five fully enclosed brackets: (A1*(A2*(A3 * A4 ))), (A1*(A2 * A3) * A4), (A1 * A2) * (A3 * A4 )),

(A1 * A2) * A3) * A4 ). Each type of brackets determines the order of calculation. Different computing sequences are closely related to the calculation of matrix concatenation. I will not go into details about how to multiply matrices here. Please refer to about matrix.

Consider the concatenation of the three matrices {A1, A2, A3}. Assume that the dimensions of these three matrices are 10x100,100x5, 5x50, respectively. If the calculation is based on (A1 * A2) * A3), the calculation frequency is 10 × 100 × 5 + 10 × 5 × 50 = 7500.

If the calculation is based on (A1*(A2 * A3), the calculation frequency is 100 × 5 × 50 + 10 × 100 × 50 = 75000. The number of computing times for the 1st methods is 10 times that for the latter! It can be seen that different brackets are used to determine different calculation order pairs.

The calculation workload of matrix multiplication is huge.

Matrix concatenation is defined as follows: given n matrices {A1, A2 ,..., an}, the dimension of matrix A1 is pi-1 × Pi, I = 1, 2 ,..., n, how to concatenate A1 * A2 *.... * An is fully enclosed in brackets and uses matrix multiplication to calculate the least number of times.

Problem Analysis

If we use the exhaustive method, we can prove that it takes exponential time to solve the problem. However, the time is expensive. Now we want to use dynamic planning to solve the multiplication problem.

For convenience, use AI... J to represent the result of matrix multiplication of ai * Ai + 1 *... AJ. Where I <j. Then ai * Ai + 1 *... AJ must be split between AK and aK + 1. I <= k <j. Problem ai * Ai + 1... AJ the overhead of full brackets equals to the computing matrix

The overhead of AI... K and computing aK + 1... j plus the overhead of multiplying their results. The optimal sub-structure of the problem can be described as follows: assume that the problem ai * Ai + 1 *... AJ is fully enclosed in brackets. The optimal method is to split the AK between AK and aK + 1, so the split

Then, the optimal ai * Ai + 1 *.... AI * Ai + 1 in AJ .... AK must be a problem: ai * Ai + 1 *... * The best bracket mode of AK. Similarly, the sub-chain of the optimal aK + 1 * ak + 2 *... AJ must be the problem aK + 1 * ak + 2 *... AJ optimal bracket mode.

According to the above analysis, Set M [I, j] to calculate AI... the minimum computing times required by j m [I, j] = min {M [I, K] + M [k + 1, J] + pi-1pKpj}

Solution

# Include <iostream> void main () {int M [8] [8], min; int R [8] = {10, 20, 50, 1,100, 4, 20, 2};/* matrix dimension * // * initialization */memset (M, 0, sizeof (m )); /* Add one per increment */For (int l = 1; L <7; l ++) {/* for two elements whose difference is L */For (INT I = 1; I <= 7-L; I ++) {J = I + L; /* Minimum Combination Method */min = m [I] [I] + M [I + 1] [J] + R [I-1] * R [I] * R [j]; middle [I] [J] = I; for (int K = I + 1; k <j; k ++) {If (min> M [I] [k] + M [k + 1] [J] + R [I-1] * R [k] * R [J]) {min = m [I] [k] + M [k + 1] [J] + R [I-1] * R [k] * R [J]; middle [I] [J] = K ;}} M [I] [J] = min ;}} STD: cout <m [1] [N];}

From the above code, we can easily see that the time complexity of the algorithm is O (n ^ 3 ). Even so, it is faster than the exhaustive method's exponential time complexity.

Conclusion

Dynamic Planning is definitely not clear in one or two articles. Of course, you can't fully learn it through one or two questions. The key to learning is to use the idea of motion planning to think about problems and design the state transfer equation.

There are still many variants in dynamic planning, such as State compression and tree shapes. Although these questions are hard to answer, I listened to songs while I was away from work and study. It's also a great deal of life.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.