Backpack problems:
Given n items (each item only has one) and a backpack. The Weight of item I is wi, the value is pi, and the size of the backpack is w. Q: How should I select an item and load it into a backpack to maximize the total value?
L if an item can be cut when it is loaded into a backpack, it can be loaded into only one part. In this case, the problem is called a backpack problem.
L when loading a backpack, each type of item I has only two options: loading or not loading, neither loading multiple times nor loading only a part. Therefore, this problem is called the 0-1 backpack problem.
To get the optimal solution, we need to find a balance between the increase in efficiency and the consumption of backpack capacity. That is to say, we should always put those objects with the highest benefits in a backpack first.
Backpack problems can be seen as a backtracing:
Each package is a node, with two candidate values 0 and 1. 0 indicates not putting people in the backpack, and 1 indicates putting them in the backpack.
Therefore, the knapsack problem is converted to finding a path that meets the conditions.
Therefore, the solution can be traced back.
Backtracing solves the problem of a backpack:
Method 1:
// Determine whether the node (I, j) is a node in the solution path:
//
// I indicates the I-th test node in the solution path, and j indicates a candidate value for the node.
// A [I] Save the value selected for node I
BOOL TestNode (I, j)
{
Update related parameter values (assuming this candidate value j is selected, so the affected parameter values are updated );
With 0-(I-1) layer to determine whether there is a conflict with the node to traverse
If a conflict exists, FALSE is returned;
If no conflict exists, save the node I value j to the corresponding array. A [I] = J;
Determine whether I is the last layer,
If it is the last layer, a path is successfully found and TRUE is returned;
If it is not the last layer, determine whether the I + 1 layer has the correct node.
BOOL bFlag = FALSE;
FOR (k = 0; k <CANDIDATA_NUM; k ++) // candidate value [0,..., CANDIDATA_NUM-1]
{
If (TestNode (I + 1, k ))
{
Find a solution;
BFlag = True;
}
// No matter whether TestNode (I + 1, k) is successful or failed, the parameters must be restored after exiting.
Restore related parameter values (the candidate value k is revoked, so the affected parameter values must be restored );
}
RETURN bFlag;
}
[Cpp]
Int m, n = 5, x [10] = {0 };
Int w [6] = {0, 2, 6, 5}, v [6] = {0, 6, 3, 5, 4, 6 };
Int c = 10;
Int cw = 0, cv = 0, bestv = 0;
BOOL TestNode (int I, int j) {// The candidate values for item I are 0 and 1
// Update related parameter values
Cw + = w [I] * j;
Cv + = v [I] * j;
// Conflict with the previous item
If (cw> c)
Return FALSE;
// No conflict. Add it to the solution path.
X [I] = j;
// No conflict exists between 0 and I.
// If the last row successfully finds a solution
If (I = n ){
For (I = 1; I <= n; I ++)
Printf ("% d", x [I]);
If (cv> bestv)
Bestv = cv;
Printf ("\ n ");
Return TRUE;
}
// If it is not the last row, the I + 1 row will be judged
BOOL bSuit = FALSE;
For (int k = 0; k <= 1; k ++)
{
// A proper position exists in line I + 1
If (TestNode (I + 1, k ))
BSuit = TRUE;
// Restore related parameters
Cw-= w [I + 1] * k;
Cv-= v [I + 1] * k;
}
Return bSuit;
}
Void Bag ()
{
For (int I = 0; I <= 1; I ++)
{
TestNode (1, I );
}
}
Or do not update or restore the relevant variables, but deduct the relevant variable values based on known information.
[Cpp]
Int m, n = 5, x [10] = {0 };
Int w [6] = {0, 2, 6, 5}, v [6] = {0, 6, 3, 5, 4, 6 };
Int c = 10;
Int cw = 0, cv = 0, bestv = 0;
BOOL TestNode (int I, int j) {// The candidate values for item I are 0 and 1
// Based on known Parameters
Cw = 0;
Cv = 0;
For (int k = 1; k <= I-1; k ++)
{
Cw + = x [k] * w [k];
Cv + = x [k] * v [k];
}
Cw + = w [I] * j;
Cv + = v [I] * j;
// Conflict with the previous item
If (cw> c)
Return FALSE;
// No conflict. Add it to the solution path.
X [I] = j;
// No conflict exists between 0 and I.
// If the last row successfully finds a solution
If (I = n ){
For (I = 1; I <= n; I ++)
Printf ("% d", x [I]);
If (cv> bestv)
Bestv = cv;
Printf ("\ n ");
Return TRUE;
}
// If it is not the last row, the I + 1 row will be judged
BOOL bSuit = FALSE;
For (int k = 0; k <= 1; k ++)
{
// A proper position exists in line I + 1
If (TestNode (I + 1, k ))
BSuit = TRUE;
}
Return bSuit;
}
Void Bag ()
{
For (int I = 0; I <= 1; I ++)
{
TestNode (1, I );
}
}
Method 2:
The algorithm can be simplified based on the particularity of the knapsack problem.
[Cpp]
Int m, n = 5, x [10] = {0 };
Int w [6] = {0, 2, 6, 5}, v [6] = {0, 6, 3, 5, 4, 6 };
Int c = 10;
Int cw = 0, cv = 0, bestv = 0;
Int OK (int k)
{
Int u = 1;
If (cw> c)
U = 0;
Return u;
}
Int f (int k)
{
Int I;
If (k> n)
{
For (I = 1; I <= n; I ++)
Printf ("% d", x [I]);
If (cv> bestv)
Bestv = cv;
Printf ("\ n ");
}
Else
{
X [k] = 1; // judge candidate value 1
Cw + = w [k];
Cv + = v [k];
If (OK (k ))
F (k + 1 );
Cw-= w [k]; // judge the candidate value 0
Cv-= v [k];
X [k] = 0;
If (OK (k ))
F (k + 1 );
}
Return k;
}
Author: shuilan0066