0/1 the Dynamic Programming Method for Solving the knapsack problem was described by our predecessors. What we did here was to implement it based on our own understanding. The main purpose was to train our thinking and programming skills. At the same time, it is also to enhance understanding and grasp of the dynamic planning mechanism.
It is worth mentioning that, in Java implementation, is modeling by algorithm model or object model? If an algorithm model is used, the value and weight of the backpack are directly stored in two groups. If an object model is used, Object Modeling is required for the problem of the backpack and the backpack. After thinking about it, I still use the object model, although I feel that the algorithm model seems better. Sometimes this is true. Although the object model is very popular, it is not omnipotent. using other models and perspectives may provide better solutions.
Backpack Modeling:
Package algorithm. dynamicplan; public class knapsack {/** backpack weight */private int weight;/** backpack item value */private int value; /***** constructor */Public knapsack (INT weight, int value) {This. value = value; this. weight = weight;} public int getweight () {return weight;} public int getvalue () {return value;} Public String tostring () {return "[weight: "+ weight +" "+" value: "+ value +"] ";}}
Solve the knapsack problem:
/*** Solve the knapsack problem: * given n backpacks, their weights are W1, W2 ,......, Wn, which has the following values: V1, V2 ,......, Vn * to put the total load in a totalweight box, * calculate the maximum value of the total value of the backpack that can be placed in the box. ** Note: Use the Dynamic Programming Method to Solve the knapsack problem * set the first n backpacks. The optimal load-bearing value of J is V [N, J], and the optimal solution is B [N]. * optimal solution: * 1. if j <wn, V [N, J] = V [n-1, J]; * 2. if j> = wn, V [N, J] = max {v [n-1, J], vn + V [n-1, J-wn]}. ** Optimal solution: * 1. if V [N, J]> V [n-1, J], the backpack N is selected as B [N], * 2. then solve the first n-1 backpack into the total load of J-wn, * so we should judge V [n-1, J-wn] vs V [N-2, J-wn], determines whether or not the n-1 backpack is selected. * 3. push backward until the total load is zero. ** Focus: master the analysis methods and Implementation ideas for solving problems using dynamic programming. * Analysis method: the optimal solution S (n) of the problem instance P (n) contains the optimal solution S (n-1) of the problem instance P (n-1); * in S (n-1) construction of S (n) * Implementation idea: bottom-up iterative solution and memory-based top-down recursion */package algorithm. dynamicplan; import Java. util. arraylist; public class knapsackproblem {/** specify a backpack */private knapsack [] bags;/** total load **/private int totalweight; /** specify the number of backpacks */private int N;/** specify the Top N backpacks. The total load is the optimal matrix of totalweight. */private int [] [] bestvalues; /** the first n backpacks have the optimal load of totalweight */private int bestvalue;/** the first n backpacks, components with the optimal totalweight load: */private arraylist <knapsack> bestsolution; Public knapsackproblem (Knapsack [] Bags, int totalweight) {This. bags = bags; this. totalweight = totalweight; this. N = bags. length; If (bestvalues = NULL) {bestvalues = new int [n + 1] [totalweight + 1] ;}} /*** solve the problem of the first n backpacks whose total load is totalweight. **/Public void solve () {system. out. println ("given backpack:"); For (Knapsack B: bags) {system. out. println (B);} system. out. println ("given total load:" + totalweight); // obtain the optimal value for (Int J = 0; j <= totalweight; j ++) {for (INT I = 0; I <= N; I ++) {if (I = 0 | j = 0) {bestvalues [I] [J] = 0 ;} else {// if the weight of the I-th backpack is greater than the total load, the optimal solution exists in the former I-1 backpack, // note: the I backpack is bags [I-1] If (j <bags [I-1]. getweight () {bestvalues [I] [J] = bestvalues [I-1] [J];} else {// If the I-th backpack is less than the total load-bearing, the optimal solution is either the optimal solution that contains the I-th backpack, // or the optimal solution that does not contain the I-th backpack. the maximum value of the two is obtained, here we use the classification discussion method // I the weight of the backpack iweight and the value of ivalueint iweight = bags [I-1]. getweight (); int ivalue = bags [I-1]. getvalue (); bestvalues [I] [J] = math. max (bestvalues [I-1] [J], ivalue + bestvalues [I-1] [J-iweight]);} // else} // For a backpack to form if (bestsolution = NULL) {bestsolution = new arraylist <knapsack> ();} int tempweight = totalweight; For (INT I = N; I> = 1; I --) {If (bestvalues [I] [tempweight]> bestvalues [I-1] [tempweight]) {bestsolution. add (Bags [I-1]); // bags [I-1] indicates the I-th backpack tempweight-= bags [I-1]. getweight () ;}if (tempweight = 0) {break ;}} bestvalue = bestvalues [N] [totalweight];}/*** get the first n backpacks, optimal Solution value for a backpack whose total load is totalweight * Call condition: the solve method must be called first **/Public int getbestvalue () {return bestvalue ;} /*** obtain the optimal solution matrix of the First n backpacks whose total load is totalweight * Call conditions: you must first call the solve method **/Public int [] [] getbestvalues () {return bestvalues;}/*** to obtain the first n backpacks, optimal Solution matrix for a backpack with a total load of totalweight * Call condition: the solve method must be called first **/Public arraylist <knapsack> getbestsolution () {return bestsolution ;}}
Test the knapsack problem:
Package algorithm. dynamicplan; public class knapsacktest {public static void main (string [] ARGs) {knapsack [] bags = new knapsack [] {New knapsack (), new knapsack ), new knapsack (), new knapsack (), new knapsack (1, 8 )}; int totalweight = 12; knapsackproblem Kp = new knapsackproblem (bags, totalweight); KP. solve (); system. out. println ("-------- solution of this backpack problem instance: ---------"); system. out. println ("optimal value:" + KP. getbestvalue (); system. out. println ("optimal solution [Selected backpack]:"); system. out. println (KP. getbestsolution (); system. out. println ("optimal value matrix:"); int [] [] bestvalues = KP. getbestvalues (); For (INT I = 0; I <bestvalues. length; I ++) {for (Int J = 0; j <bestvalues [I]. length; j ++) {system. out. printf ("%-5d", bestvalues [I] [J]);} system. out. println ();}}}
Summary of dynamic planning:
1. Dynamic programming is used to solve non-optimal problems:
When the problem instance P (n) is resolved by the sub-problem instance, for example, P (n) = P (n-1) + P (n-2) [Fibonacci series], P (n-1) and P (n-2) may contain overlapping subproblems, you can use the dynamic programming method, through the bottom-up iteration, to solve more than the example of the problem, it serves as the basis for solving large subproblem instances. The key idea is to avoid repeated solutions to subproblems.
For example, evaluate the Fibonacci number F (5 ):
F (5) = f (4) + f (3 );
Subproblem: F (4) = f (3) + F (2 );
F (3) = F (2) + F (1 );
F (2) = F (1) + f (0)
F (2) = F (1) + f (0 );
Subproblem: F (3) = F (2) + F (1)
F (2) = F (1) + f (0)
From the above calculation process, we can see that if the recursive formula is used, then the sub-problem F (2) is repeatedly calculated twice. When the problem instance is large, solving these repeated subproblems takes a lot of unnecessary time. If the dynamic programming method is used to store the values of F (2), it can save a lot of time if the values are obtained directly when the calculation is required.
Another typical example is: solving the binary coefficient C (n, k) = C (n-1, k) + C (n-1, k-1)
2. Dynamic Programming to solve the optimization problem:
When the optimal solution of the problem instance P (n) can be constructed from the optimal solution of the problem instance P (n-1), the dynamic programming method can be used to construct the optimal solution step by step.
The key is to master the analysis method when solving the problem by using the dynamic programming method, and how to export the recursive formula of the solution from the problem. In fact, after exporting the recursive formula of the knapsack problem, the subsequent work was much simpler. How to analyze the knapsack problem and export the recursive formula of its optimal solution? I think, this is the key! Problem analysis is very important!