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