Dynamic Planning and two examples, planning two examples
Now we need to clarify these common algorithms, or else we can only be a low-level programmer.
Dynamic Programming (DP) is the optimal mathematical method for solving the decision-making process. Dynamic Planning is generally divided into linear motion gauge, regional motion gauge, tree motion gauge, and backpack motion gauge.
Dynamic Planning is a method, but not an algorithm. It is generally used for optimization problems in multiple decision-making and has the idea of recursion. Dynamic Planning is similar to divide and conquer. The basic idea is to break down the problem to be solved into several subproblems. First, solve the subproblems and then obtain the original solution from the subproblems. However, the sub-problems obtained from the splitting method are independent of each other, but they are not in dynamic planning. The basic idea of dynamic planning is similar to the divide and conquer method. It also records the answers to all resolved subquestions in a table. If the problem is used in the future, it will be filled in the table. In multiple decision-making processes, decisions in various stages depend on the current state, and then lead to state transfer. A decision sequence is generated in a changed state, so it is dynamic.
Use Dynamic Planning to solve the problem:
1. 01 backpack.
There is a package and n items, the package capacity is m, each item has its own volume and value, q: What is the maximum value that can be obtained when multiple items are selected from the n items and the total volume of items does not exceed the capacity m of the package? [Each item cannot be retrieved multiple times. It can only be retrieved once at most. The reason is "01 backpack". 0 indicates not to be retrieved, and 1 indicates to be retrieved.]
First make a simple version, that is, the item has no value, and only calculates the total volume of the most items that can be placed.
It is easy to obtain a simple recursive version:
int getMax(int* p ,int beglast,int arraylast){if(arraylast<1)return 0;int put,noput;noput = getMax(p+1,beglast,arraylast-1);if(*p <= beglast){put = *p + getMax(p+1,beglast - *p,arraylast-1);}elseput = noput;if(put > noput)return put;elsereturn noput;}int main(){int a[] = {3,3,5,1,1,2,5,4,3,3};cout<<getMax(a,10,10);system("pause");}
The question is reduced here. For the first item, if it is placed, the maximum capacity after the first item is calculated, and the first item is added, compared with the maximum capacity obtained if the first item is not placed, the maximum size is the total size of the most items in the current backpack. What is important here is that adding or not joining a backpack to any object will affect the maximum capacity of the subsequent item, and dynamic planning is reflected here, so here we will traverse all the situations, that is, the complexity is O (n * n ). In fact, this is the simplest way to solve such problems, that is, traversing all may calculate the maximum value, but recursion is used here to make it more readable.
To make it more efficient, we need to convert recursion into a loop. There are two methods to store data recursively,
One is to use the Data1 and Data2 arrays to record the results of the previous stage, then release the corresponding Data2 according to Data1, then copy Data2 to Data1, and then continue, in this way, if each time it is a simple recursive first-level operation, but frequent assignment is troublesome, you can use deque in STL, in addition, this method is not suitable for Recursive problems that are related to the above-level stages.
The other is to create an array of Data [0... n], record the last N-level stored data. When the current stage requires data in method phase k, ACCESS data [k MOD (N + 1.
Try to use your own ideas to change this recursive process to a loop process:
Int getMaxBegA (int obj [], int const objn, int value [], int begsize) {// for this table, fill in the remaining backpack volume and int ** p = new int * [++ begsize] for the nth stone; int ** v = new int * [begsize]; for (int I = 0; I <begsize; I ++) {p [I] = new int [objn]; v [I] = new int [objn];} for (int I = 0; I <begsize; I ++) {if (I> = obj [objn-1]) {v [I] [objn-1] = value [objn-1]; p [I] [objn-1] = obj [objn-1];} else {v [I] [objn-1] = 0; p [I] [objn-1] = 0 ;}} int a, B; for (int I = objn-2; I>-1; I --) {for (int j = 0; j <begsize; j ++) {if (j <obj [I]) {p [j] [I] = p [j] [I + 1]; v [j] [I] = v [j] [I + 1];} else {a = value [I] + v [j-obj [I] [I + 1]; B = v [j] [I + 1]; if (a> B) {v [j] [I] =; p [j] [I] = obj [I] + p [j-obj [I] [I + 1];} else {p [j] [I] = p [j] [I + 1]; v [j] [I] = v [j] [I + 1] ;}}}for (int I = 0; I <objn; I ++) {cout <I <":"; for (int j = 0; j <begsize; j ++) {cout <p [j] [I] <";}cout <endl;} a = v [begsize-1] [0]; for (int I = 0; I <begsize; I ++) {delete [] p [I]; delete [] v [I];} delete [] p; delete [] v; return ;}
In fact, the best way to fill in the dynamic planning is to create a two-dimensional table with rows representing the decision stage and columns representing the decision state, but I am just turning it back here. By filling out a table, duplicate calculation is not required for repeated issues, but a large amount of space is required. If you want to improve the space complexity, perform the optimization mentioned above, that is, each new stage depends on the results of different states from the previous stage, however, when we move from backward to the first stage, we only need the data in the second stage, so we do not need to save unnecessary data, however, every time you change to a new stage, you have to re-assign the value of the previous result, and the time will be more complicated.
After reading the algorithm of the most advanced sequence in the beauty of programming, I tried to write a similar solution:
int L10(int obj[],int value[],int maxbeg,int size){int* LW = new int [size];int* LV = new int[size];for(int i = 0 ; i < size;i++){if(obj[i] <= maxbeg){LW[i] = obj[i];LV[i] = value[i];}else{LW[i] = 0;LV[i] = 0;}for(int j = 0 ; j < i;j++){if(LV[j]+ value[i] > LV[i] && obj[i]+LW[j] <= maxbeg){LV[i] = LV[j] + value[i];LW[i] = LW[j] + obj[i];}}}int MAX = 0;for(int i =0; i < size;i++){if(LV[i] > MAX)MAX = LV[i];}return MAX;}
If we find this, we can get the correct results. Is this method a common method to solve most of the dynamic planning problems?
Then, consider a common topic of dynamic planning:
Set L = <a1, a2 ,..., An> is a sequence of n different real numbers. The ascending subsequence of L is such a subsequence Lin = <aK1, ak2 ,..., Akm>, where k1 <k2 <... <Km and aK1 <ak2 <... <Akm. Evaluate the maximum m value.
Simple recursive algorithms:
int getMaxLengthArray(int stack[],int stacktop,int array[],int arraysize){int length = 0,mis,re ;if(arraysize<1)return 0;if( *array > stack[stacktop] ){mis = getMaxLengthArray(stack,stacktop,array+1,arraysize-1);stack[stacktop+1] = *array++;re = 1+getMaxLengthArray(stack,stacktop+1,array,arraysize-1);if(mis > re)return mis;else return re;}if( *array == stack[stacktop]){return getMaxLengthArray(stack,stacktop,array+1,arraysize-1);}if(*array < stack[stacktop]){mis = getMaxLengthArray(stack,stacktop,array+1,arraysize-1);int n = 0;while( *array <= stack[stacktop] ){stacktop--;n++;}stack[++stacktop] = *array;re = getMaxLengthArray(stack,stacktop,array+1,arraysize-1) - n ;if(re>mis)return re;else return mis;}}int getMax(int array[],int arraysize){int* stack = new int[arraysize+1];stack[0] = 0xFFFFFFFF;return getMaxLengthArray(stack,0,array,arraysize);}
Backtracing is also needed here. Because I haven't studied backtracing yet, I can only use a simple method to implement backtracing, that is, using stacks to record the computing process, then, the stack is used to simulate backtracking.
The algorithms here are not reasonable and concise. Programming is written in the US-China-US-China region as follows:
Int LISA (int array [], int size) {int * LIS = new int [size]; int MAX, I, j; for (I = 0; I <size; I ++) {LIS [I] = 1; for (j = 0; j <I; j ++) {// here for traversing to the I element, traverse the first I element. If the current I element is added to the previous j element, the length of its child // string increases, record the current maximum number of fields of the new node I. If (array [j] <array [I] & LIS [j] + 1> LIS [I]) LIS [I] = LIS [j] + 1 ;}} MAX = 1; for (I = 0; I <size; I ++) {if (LIS [I]> MAX) MAX = LIS [I];} delete [] LIS; return MAX ;}
This is simple, but the beauty of programming is not enough. The beauty of programming is like this, A new array is used to store the minimum value of the current longest and the maximum values corresponding to the longest sequence. If MaxV is used as an array, when the value of MAXV [I] is the number j of the string currently traversed, the maximum value of the Child segment with the previous length of I is the minimum value of the rightmost vertex. For vertex j, when finding a child sequence that suits you, it must start from the first largest child sequence. When the maximum value of the longest child sequence is less than the value of j, it means that the j point can be connected to the oldest sequence, and then the information is updated to change the rightmost vertex value of the oldest sequence of the table to the value of j. This record also needs to be updated when j points are not longer than the current maximum subsequence, that is, the obtained length is still the length of the existing subsequence, at this time, we need to update the minimum value of the maximum value corresponding to this length, that is, to determine that the value release of the j point is smaller than the current maximum value of this length. Because the current maximum length of the longest child sequence is increased at the first level, the array of the current Child sequence length of this record is continuous and the current maximum value is recorded, when searching, you only need to start from the maximum value and look down. But it is still o (N * N ),.
The further optimization of the beauty of programming is to change the downward o (N) search to binary search, so that the search complexity becomes O (log2 N ). The complexity of the entire process has also changed to O (N * log2 N), which is too troublesome for me to implement.
Examples of Dynamic Planning Count
This is an experimental course for Algorithm Design in the computer system. The following describes the dynamic planning content:
Experiment 4: Dynamic Planning
Objective: To understand the basic idea of dynamic planning and the overlapping nature of subproblems and the two basic elements of the dynamic planning algorithm. Master typical dynamic planning problems. Master the general methods for analyzing dynamic planning ideas, correctly analyze simple problems, design dynamic planning algorithms, and implement programming quickly.
Experiment content: Examples of programming implementation: Longest Common subsequence problem, matrix concatenation problem, convex polygon optimal triangle division problem, Circuit Wiring Problem, etc. In this experiment, we design algorithms and program them.
Exercise
1. Longest Common subsequence
The subsequence of a given sequence is obtained after several elements are deleted from the sequence. To be exact, if the given sequence X = <x1, x2 ,..., Xm>, then another sequence Z = <z1, z2 ,..., Zk> is the subsequence of X, which refers to the existence of a strictly incrementing subscript sequence <i1, i2 ,..., Ik>, so that for all j = 1, 2 ,..., K has
The answer is as follows:
A) Structure of the longest common subsequence
If the exhaustive search method is used, the time is too long and the algorithm requires exponential time.
The longest common subsequence of Yizheng is also of the optimal sub-structure.
Set sequence X = <x1, x2 ,..., Xm> and Y = <y1, y2 ,..., One of the longest common subsequences of yn> Z = <z1, z2 ,..., Zk>, then:
I. If xm = yn, zk = xm = yn and the Zk-1 is the longest common subsequence of Xm-1 and Yn-1;
Ii. If xm =yn and zk =xm, Z is the longest common subsequence of Xm-1 and Y;
Iii. If xm =yn and zk =yn, Z is the longest common subsequence of X and Yn-1.
The Xm-1 = <x1, x2 ,..., Xm-1>, Yn-1 = <y1, y2 ,..., Yn-1>, Zk-1 = <z1, z2 ,..., Zk-1>.
The longest common subsequence problem has the optimal substructure.
B) recursive structure of subproblems
According to the optimal sub-structure nature of the longest common subsequence problem, we need to find X = <x1, x2 ,..., Xm> and Y = <y1, y2 ,..., The longest common subsequence of yn> can be recursively performed in the following way: When xm = yn, find the longest common subsequence of Xm-1 and Yn-1, add xm (= yn) to the end of the sequence to obtain the longest common subsequence of X and Y. When xm =yn, two subproblems must be solved: finding one of the longest common subsequences of Xm-1 and Y and one of the longest common subsequences of X and Yn-1. The elders of the two common subsequences are the longest common subsequences of X and Y.
From this recursive structure, it is easy to see that the longest common subsequence problem has subproblem overlapping nature. For example, when calculating the longest common subsequences of X and Y, the longest common subsequences of X and Yn-1 and Xm-1 and Y may be calculated. Both of these subproblems contain a common subproblem, that is, the longest common subsequence for calculating Xm-1 and Yn-1.
Let's establish a recursive relationship between the Optimal Values of sub-problems. Use c [I, j] to record the length of the longest common subsequence of sequence Xi and Yj. Xi = <x1, x2 ,..., Xi>, Yj = <y1, y2 ,..., Yj>. When I = 0 or j = 0, the null sequence is the longest common subsequence of Xi and Yj, So c [I, j] = 0. Build a recursive relationship as follows:
C) Calculate the optimal value
In the subproblem space, there are only θ (m * n) Different subproblems. Therefore, using the dynamic planning algorithm to calculate the optimal value from the bottom up can improve the efficiency of the algorithm.
The Dynamic Programming Algorithm LCS_LENGTH (X, Y) used to calculate the longest common sub-sequence length ,..., Xm> and Y = <y1, y2 ,..., Yn> as input. Output two arrays c [0 .. m, 0 .. n] and B [1 .. m, 1 .. n]. Among them, c... the remaining full text>
Dynamic Planning short circuit example
Problem description
Set A and B to two strings. Use the minimum number of characters to convert string A to string B. The character operations mentioned here include: (1) deleting one character; (2) Inserting one character; (3) changing one character to another. The minimum number of characters used to convert string A to string B is the distance from string A to string B and is recorded as d (A, B ). Design an effective algorithm to calculate the editing distance between any two strings, A and B ).
Input
The first line of the input is string A, and the second line of the file is string B.
Output
When the program is running, the distance from d (A, B) will be edited and output.
Sample Input
Fxpimu
Xwrs
Sample Output
5
Please provide the complete code