Turn https://www.cnblogs.com/Christal-R/p/Dynamic_programming.html
Problem Description: There are n items, they have their own weight and value, given the existing capacity of the backpack, how to get the items into the backpack has a maximum value of the sum?
Third, the principle of dynamic programming and process:
eg:number=4,capacity=8
i |
1 |
2 |
3 |
4 |
w (by volume) |
2 |
3 |
4 |
5 |
v (value) |
3 |
4 |
5 |
6 |
Definition of V (i, j): the current capacity of the backpack j, i-th former best combination of values corresponding to the article;
Looking recurrence relations, the face of the commodity there are two possibilities:
First, the capacity of the packet is smaller than the volume of goods, fit, the value of the previous i-1 th value at this time is the same, i.e., V (i, j) = V (i-1, j);
Second, there is enough capacity can hold the product, but not necessarily installed reach the optimal current value, so the best choice between a loaded and not loaded, i.e., V (i, j) = max {V (i-1, j), V (i-1, jw (i)) + v (i)}
Where V (i-1, j) represents not loaded, V (i-1, jw (i)) + v (i) represents the installed i-th commodity, backpacks capacity decreases w (i), but the value increases V ( I);
It follows recurrence relation:
1) j<w(i) V(i,j)=V(i-1,j)
2) j>=w(i) V(i,j)=max{ V(i-1,j),V(i-1,j-w(i))+v(i) }
Sheet, first initializes the boundary conditions, V (0, j) = V (i, 0) = 0;
h) and then fill in a form line by line,
1), i = 1, j = 1, w (1) = 2, v (1) = 3, there are j <w (1), so that V (1,1) = V (1-1,1) = 0;
2) Another example i = 1, j = 2, w (1) = 2, v (1) = 3, there are j = w (1), so that V (1,2) = max {V (1-1, 2), V (1-1,2-w (1)) + v (1)} = max {0,0 + 3} = 3;
3) Under such circumstances, to fill the last, i = 4, j = 8, w (4) = 5, v (4) = 6, there are j> w (4), so that V (4,8) = max { V (4-1,8), V (4-1,8-w (4)) + v (4)} = max {9,4 + 6} = 10; so table has been completed as shown below:
1 void FindMax () // Dynamic Programming 2 { . 3 int I, J; . 4 // sheet . 5 for (I =. 1; I <= Number; I ++) . 6 { . 7 for (J =. 1; J <= Capacity; ++ J) . 8 { . 9 IF (J <W [I]) // not into the package 10 { . 11 V [I] [J] = V [. 1-I] [J]; 12 is} 13 is able to install the else // 14 { 15 if (V [i-1 ] [j]> V [i-1] [jw [i]] + v [i]) // not a large value means 16 { . 17 V [I] [J] = V [ i-1] [J]; 18 is} . 19 and the else // optimum value of the i-th item of the article before the i-1 th and greater 20 { 21 is V [i] [J] = V [I- 1] [jw [i]] + v [i]; 22} 23} 24} 25 } 26 }
i) to complete the form, i.e., the optimal solution is V (number, capacity) = V (4,8) = 10, it is not known what product solution composed of, so to find a solution to the composition according to the optimal solution backtracking, according to the principle of filling may have to find a solution as follows:
1) V (i, j) = V (i-1, when J), described the i-th commodity is not selected, the process returns to V (i-1, j);
2) V (i, j) = V (i-1, jw (i)) + v (i) in real time, the apparatus described the i-th commodity, the commodity is composed of a part of the optimal solution, then we have to return before loading the product, i.e. back to V (i-1, jw (i));
3) has been traversed to i = 0 until the end, consisting of all solutions will be found.
j) As an example,
1) the optimal solution V (4,8) = 10, and V (4,8)! = V (3,8) there are V (4,8) = V (3,8-w (4)) + v (4) = V (3,3) + 6 = 4 + 6 = 10, so that the fourth item is selected, and back to V (3,8-w (4)) = V (3,3) ;
2) V (3,3) = V (2,3) = 4, so that the third item is not selected, back to V (2,3);
3) V (2,3)! = V (1,3) there are V (2,3) = V (1,3-w (2)) + v (2) = V (1,0) + 4 = 4 + 0 = 4, so the second item is selected, and back to V (1,3-w (2)) = V (1,0);
4) V (1,0) = V (0,0) = 0, so the first item is not selected;
k) to this, 01 knapsack problem has been solved by using dynamic programming solution to this problem is to fill the efficiency of this efficiency, ie tables, so time efficiency of dynamic programming is O (number * capacity) = O (n * c), due to the use two-dimensional array of memory sub-solution of the problem, so the space efficiency of dynamic programming is O (n * c);
1 void FindWhat (int i, int j) // Find Solution Composition embodiment 2 { . 3 IF (I> = 0) . 4 { . 5 IF (V [I] [J] == V [. 1-I] [J] ) // not equal described apparatus . 6 { . 7 Item [I] = 0; // global variable mark is not selected . 8 the FindWhat (. 1-I, J); . 9} 10 the else IF (JW [I]> = 0 && V [I] [J] == V [-I. 1] [JW [I]] + V [I]) . 11 { 12 is Item [I] =. 1; // tag is selected 13 FindWhat (i-1, jw [i]); // return to the position before the bundles 14} 15} 16}
3, space optimization
l) the optimization space, each value V (i) (j) changed only with V (i-1) (x) {x: 1 ... j} related, V (i-1) (x) is a front a down cycle i saved value;
Thus, V may be reduced to a one-dimensional array, so as to achieve the purpose of optimizing space, state transition equation is converted to B (J) = max {B (J), B (JW (I)) + V (I)} ;
Further, the state transition equation, each derived V (i) (j) by V (i-1) (jw (i)) is derived, so that one-dimensional array to be scanned in descending order of j (Capacity to 0), one cycle before preserved whether those values will be modified, resulting in an error.
m) Similarly to the above example will be described with i = 3, there are:
1) i=3,j=8,w(3)=4,v(3)=5,有j>w(3),则B(8)=max{B(8),B(8-w(3))+v(3)}=max{B(8),B(4)+5}=max{7,4+5}=9;
2) j- - i.e., j = 7, there are j> w (3), then B (7) = max {B (7), B (7-w (3)) + v (3)} = max {B (7), B (3) +5} = max {7,4 + 5} = 9;
3) j- - i.e., j = 6, there are j> w (3), the B (6) = max {B (6), B (6-w (3)) + v (3)} = max {B (6), B (2) +5} = max {7,3 + 5} = 8;
4) j- - i.e., j = 5, there are j> w (3), then B (5) = max {B (5), B (5-w (3)) + v (3)} = max {B (5), B (1) +5} = max {7,0 + 5} = 7;
5) j- - i.e., j = 4, there are j = w (3), then B (4) = max {B (4), B (4-w (3)) + v (3)} = max {B (4), B (0) +5} = max {4,0 + 5} = 5;
6) j- - i.e., j = 3, there are j <w (3), there will continue to access the array bounds, the round operation is stopped, B (0) to a value B (3) of the upper retention loop (i = 2 value) does not change into the next cycle i ++;
如果j不逆序而采用正序j=0...capacity,如上图所示,当j=8时应该有B(8)=B(8-w(3))+v(3)=B(4)+5,然而此时的B(4)已经在j=4的时候被修改过了,原来的B(4)=4,现在B(4)=5,所以计算得出B(8)=5+5=10,显然这于正确答案不符合;所以该一维数组后面的值需要前面的值进行运算再改动,如果正序便利,则前面的值将有可能被修改掉从而造成后面数据的错误;相反如果逆序遍历,先修改后面的数据再修改前面的数据,此种情况就不会出错了;
1 void FindMaxBetter()//优化空间后的动态规划 2 { 3 int i,j; 4 for(i=1;i<=number;i++) 5 { 6 for(j=capacity;j>=0;j--) 7 { 8 if(B[j]<=B[j-w[i]]+v[i] && j-w[i]>=0 )//二维变一维 9 { 10 B[j]=B[j-w[i]]+v[i]; 11 } 12 } 13 } 14 }
然而不足的是,虽然优化了动态规划的空间,但是该方法不能找到最优解的解组成,因为动态规划寻找解组成一定得在确定了最优解的前提下再往回找解的构成,而优化后的动态规划只用了一维数组,之前的数据已经被覆盖掉,所以没办法寻找,所以两种方法各有其优点。