----- Edit by ZhuSenlin HDU
I have talked about the 001 backpack in my blog <backpack problem -- "01 backpack" and its implementation (including solving specific items in the backpack)>, here we will rewrite the dynamic planning status and state equation of the 01 backpack:
Set the backpack capacity to V. There are N items in total. The size of each item is C [I], and the value of each item is W [I].
1) subproblem definition: F [I] [j] indicates the maximum value that can be obtained when several items are selected from the first I items are placed in a backpack with the free space j.
2) make a decision based on whether to place or not to place the I-th item
(1-1)
The optimal total number of solutions here refers to the maximum total number of projects.
If we set G [I] [j] to represent the total number of solutions for F [I] [j], the final result should be G [N] [V]. We initialize G [] [] as 1, because each F [I] [j] should have at least one solution, that is, the number of items selected from the first I items in the left space is j, so that the maximum number of solutions is at least 1, because F [I] [j] must exist.
The following describes how to calculate G [I] [j]. For the 01 backpack:
If F [I] [j] = F [I-1] [j] and F [I] [j]! = F [I-1] [j-C [I] + W [I] indicates that in the status [I] [j], only the placement of the item before the I-1 will maximize the value, therefore, if I items are not placed, the number of solutions to the State [I] [j] should be equal to the number of solutions in the [I-1] [j] State, that isG [I] [j] = G [I-1] [j];
If F [I] [j] = F [I-1] [j-C [I] + W [I] and F [I] [j]! = F [I-1] [j] indicates that in the status [I] [j], only the addition of the I-th item will maximize the total value, then the number of solutions should be equal to the number of [I-1] [j-C [I], that isG [I] [j] = G [I-1] [j-C [I];
If F [I] [j] = F [I-1] [j-C [I] + W [I] and F [I] [j] = F [I-1] [j] indicates that the status [I-1] [j] can be reached by the State [I] [j], the status [I-1] [j-C [I] can also be used to arrive at the status [I] [j] When I item is added, both cases make the greatest value and the two cases are mutually exclusive, so the total number of solutions isG [I] [j] = G [I-1] [j-C [I] + G [I-1] [j].
After the above analysis, the following pseudo code is obtained:
F[0][] ← 0 F[][0] ← 0 G[][ ] ← 1 for i ← 1 to N do for j ← 1 to V F[i][j] ← F[i-1][j] G[i][j] ← G[i-1][j] if (j >= C[i]) if (F[i][j] < F[i-1][j-C[i]]+W[i]) then F[i][j] ← F[i-1][j-C[i]]+W[i] G[i][j] ← G[i-1][j-C[i]] else if (F[i][j] = F[i-1][j-C[i]]+W[i]) then G[i][j] ← G[i-1][j]+G[i-1][j-C[i]] return F[N][V] and G[N][V]
The preceding method is required when the F [] [] and G [] [] statuses are saved.Space complexity of O (NV)Below we will optimize the space replication.
The compression space complexity is O (V)
F [I] [j] and G [I] [j] are only related to the states of F [I-1] [] and G [I-1, therefore, we can use two one-dimensional arrays F [] and G [] to replace the two-dimensional arrays F [] [] and G [] []. For more information, see blog
<Knapsack problem -- Explanation and implementation of "01 backpack" (including solving specific items in the backpack)>
The pseudocode is provided below:
F[] ← 0 G[] ← 1 for i ← 1 to N do for j ← V to C[i] if (F[j] < F[j-C[i]]+W[i]) then F[j] ← F[j-C[i]]+W[i] G[j] ← G[j-C[i]] else if (F[j] = F[j-C[i]]+W[i]) then G[j] ← G[j]+G[j-C[i]] return F[V] and G[V]
The following code details two types of spatial complexity of a data table:
Backpack data table (Backpack capacity 10)
Item No. I |
1 |
2 |
3 |
4 |
5 |
Volume C |
3 |
2 |
5 |
4 |
5 |
Value W |
5 |
5 |
10 |
10 |
10 |
# Include <iostream> # include <cstring> # include "CreateArray. h" // This header file dynamically creates and destroys two-dimensional arrays. You can implement using namespace std by yourself;
Time complexity O (VN), space complexity O (VN):
Int Package01Optimal (int Weight [], int Value [], int nLen, int nCapacity) {int ** MaxValueTable = NULL; int ** OptimalTable = NULL; CreateTwoDimArray (MaxValueTable, nLen + 1, nCapacity + 1); // create the maximum value table CreateTwoDimArray (OptimalTable, nLen + 1, nCapacity + 1 ); // create the optimal total number of solutions table // initiallize all OptimalTable [] [] with 1for (int I = 0; I <= nLen; I ++) for (int j = 0; j <= nCapacity; j ++) OptimalTable [I] [j] = 1; for (int I = 1; I <= nLen; I ++) {for (int j = 1; j <= nCapacity; j ++) {MaxValueTable [I] [j] = MaxValueTable [I-1] [j]; optimalTable [I] [j] = OptimalTable [I-1] [j]; if (j> = Weight [I-1]) {if (MaxValueTable [I] [j] <MaxValueTable [I-1] [j-Weight [I-1] + Value [I-1]) {MaxValueTable [I] [j] = MaxValueTable [I-1] [j-Weight [I-1] + Value [I-1]; optimalTable [I] [j] = OptimalTable [I-1] [j-Weight [I-1];} else if (MaxValueTable [I] [j] = (MaxValueTable [I-1] [j-Weight [I-1] + Value [I-1]) {OptimalTable [I] [j] = OptimalTable [I-1] [j] + OptimalTable [I-1] [j-Weight [I-1] ;}} cout <endl <"OptimalCount:" <OptimalTable [nLen] [nCapacity] <endl; int nRet = MaxValueTable [nLen] [nCapacity]; DestroyTwoDimArray (MaxValueTable, nLen + 1); // destroy the maximum value table to prevent memory leakage DestroyTwoDimArray (OptimalTable, nLen + 1); // destroy the optimal total number table to prevent memory leakage return nRet ;}
Time complexity O (VN), space complexity O (V):
int Package01Optimal_Compress(int Weight[], int Value[], int nLen, int nCapacity){int * MaxValueTable = new int [nCapacity+1];memset(MaxValueTable,0,(nCapacity+1)*sizeof(int));//initiallize all OptimalTable[] with 1int* OptimalTable = new int[nCapacity+1];for(int i = 0; i <= nCapacity; i++)OptimalTable[i] = 1;for(int i = 0; i < nLen; i++){for(int j = nCapacity; j >=Weight[i]; j--){if(MaxValueTable[j] < MaxValueTable[j-Weight[i]]+Value[i]){MaxValueTable[j] = MaxValueTable[j-Weight[i]]+Value[i];OptimalTable[j] = OptimalTable[j-Weight[i]];}else if(MaxValueTable[j] == MaxValueTable[j-Weight[i]]+Value[i])OptimalTable[j] = OptimalTable[j-Weight[i]]+OptimalTable[j];}}cout << endl << "OptimalCount:" << OptimalTable[nCapacity] << endl;int nRet = MaxValueTable[nCapacity];delete [] OptimalTable;delete [] MaxValueTable;return nRet;}
Test code:
int main(){//int Weight[] = {1,1,1,1,1,1};//int Value[] = {2,2,2,2,2,2};int Weight[] = {3,2,5,4,5};int Value[] = {5,5,10,10,10};int nCapacity = 10;cout << "MaxValue:" << Package01Optimal(Weight,Value,sizeof(Weight)/sizeof(int),nCapacity) << endl;cout << "MaxValue:" << Package01Optimal_Compress(Weight,Value,sizeof(Weight)/sizeof(int),nCapacity) << endl;return 0;}
For more information about this article, see section 9 about backpacks.