# Algorithm design and analysis training

Posted by jwright on Sat, 08 Jan 2022 10:44:53 +0100

Training documents can also be obtained directly at the end of the text
Algorithm design and analysis training

# 1. Title

0-1 knapsack problem

# 2. Purpose

The purpose of course design is to train students to flexibly apply the learned data structure knowledge and independently complete the comprehensive practical ability of the whole process of software development, such as problem analysis, overall design, detailed design and programming. Consolidate and deepen students' theoretical knowledge, improve their programming level, and cultivate their rigorous scientific attitude and good work style in this process. The course design requires independent completion of a relatively complete application requirements analysis. While completing large-scale design and programming homework, the following effects are achieved:
(1) Deepen the understanding of basic concepts, theories and methods in the course of algorithm and data structure;
(2) Train the ability to comprehensively use the knowledge learned to deal with practical problems;
(3) The level of program design and debugging has been significantly improved;
(4) Cultivate scientific software working methods.

# 3. Content

(1) Analyze the problem, model the problem, and select the appropriate data structure according to the model.
(2) The information of article number, weight and value comes from documents.
(3) Select the algorithm design strategy according to the selected data structure, and design more than two algorithms.
(4) The algorithm is designed according to the algorithm design strategy.
(5) The time complexity and space complexity of the algorithm are analyzed, and the advantages and disadvantages of the algorithm are compared.
(6) The algorithm improvement and optimization methods are discussed.

# 4. Demand analysis

(1) Problem Description: an accurate problem that requires programming to solve.
Suppose there are n items and a backpack, the corresponding value of each item i is vi, the weight is wi, and the capacity of the backpack is W. Each item has only one piece, which can be loaded or not loaded and cannot be split. When the backpack is not overweight, how to select items to load into the backpack to maximize the total value of the loaded items? What is the maximum value? What items are loaded?
(2) Functional requirements: give the functions to be realized by the program.
Enter the number n of items and the capacity w of the shopping cart, as well as the weight W and value v of each item
(3) Data requirements: input form and value range; Form of output
Please enter the number of items n:
Please enter the shopping cart capacity W:
Please enter the weight w and value v of each item in turn, separated by spaces:
(4) Test data: design test data or give specific test data. It is required that the test data can comprehensively test the function of the designed program.
Input data: 5
10
2 6 5 3 4 5 2 4 3 6

# 5. Two algorithms

## 5.1 dynamic programming method

5.1.1 analyze the problem, model the problem, and select the appropriate data structure according to the model.
There are n items, the weight of each item is W [], the value is v[i], and the capacity of the shopping cart is W. Select thousands of items
Put it into the shopping cart to maximize the value without exceeding the capacity.
(1) Determine the appropriate data structure
One dimension group w[i] and v[j] are used to record the weight and value of the i-th item: the two-dimensional array uses c[i][i] to represent the maximum value that can be obtained by putting the first I items into a shopping cart with a capacity of j.
(2) Initialization
Initialize c [] [] array 0, row 0, column 0: c[0][i]=0, c[i][0]=0, where i=0, 1, 2 n, j=0，1,2，…，W.
(3) Cycle phase
a. Calculate the processing of the first article according to the recursive formula, and get c[1][i], j=1, 2 W.
Calculate the processing of the second item according to the recursive formula, and get c[2][j], j=1, 2 W.
b. By analogy, the processing of the nth article is calculated recursively to obtain c[n][], j=1, 2 W.
(4) Construct optimal solution
c[n][W] is the maximum value of items that can be put into the shopping cart without exceeding the capacity of the shopping cart. If you want to know which items are put in, you need to construct the optimal solution inversely according to the c [[array. We can use the one dimension group x[i] to store the solution vector.
a. First, i=n, j=W. if C [i] [] > C [I-1] [], it means that the nth item is put into the shopping cart, making x[n]=1,
j-=w[n]; If c[i][j] ≤ c[i-1]i], it means that the nth item is not put into the shopping cart, so that x[n]=0.
b.i – continue to find answers.
c. Until i=1 is processed.
At this time, the solution vector (x[1], x[2],..., x[n]) has been obtained, and the solution vector can be output directly, or only the goods serial number I with x[i]=1 can be output.

5.1.2 detailed design
(1) Storage structure type definition of each abstract data type.
(2) Algorithm idea and pseudo code: describe the design idea of the algorithm to solve the corresponding problem, and design the corresponding pseudo code.

```c[i][i]Before representation i Put items into one with a capacity of j The shopping cart can get the maximum value.
Calculate the shopping cart capacity for each item j Increment from 1 to W,When the weight of the item is greater than the capacity of the shopping cart,
Do not put this item, c[i][j]=c[i- 1][j]，Otherwise, compare whether putting and not putting this item can maximize the value of the items in the shopping cart, i.e c[i[j]=max (c[i-1][j], c[i-1][j-w[i] + v[i]).
for(i=1;i<= n;i++)	//Calculation c[i] [j]
for(j=1;j<=W;j++)
if(j<w[i])	//When the weight of the item is greater than the capacity of the shopping cart, the item will not be placed
c[i][j] = c[i-1][j];
else   //Otherwise, compare whether this item can maximize the value in the shopping cart
c[i][j] = max(c[i-1] [j],c[i-1] [j-w[i]] + v[i]) ;
cout<<"The maximum value loaded into the shopping cart is:"<<c[n] [W]<<end1;
```

b. Optimal solution construction
According to the calculation results of c [] [] array, the optimal solution can be inversely recursive. A one-dimensional array x [] can be used to record the solution vector. x[i]=1 indicates that the ith item is put into the shopping cart, and x[i]=0 indicates that the ith item is not put into the shopping cart.

```first i=n，j=W:If c[j[i]>c[i-1][]，Description section i Items were put into the shopping cart, x[i]=1, j-=w[i]; otherwise x[i]=0.
i=n-1:If c[i][]>c[i-1][],Description section i Items were put into the shopping cart, x[i]=1,j- =w[i];otherwise x[i]=0.
......
i=1;If c[i][i]>c[i- 1][j],Description section i Items were put into the shopping cart, x[i]=1,j-=w[];otherwise x[i]=0.
We can output directly x[i]Solution vector, or you can only output the item serial number put into the shopping cart.
//Inverse construction of optimal solution
j=W;
for(i=n;i>0;i--)
if(c[i][j]>c[i-1][j])
{
x[i]=1;
j-=w[i];
}
else
x[i]=0;
cout<< "The items loaded into the shopping cart are:";
for(i=1;i<=n;i++)
if(x[i]==1)
cout<<i<<"";
```

(3) Draw the call diagram of functions and procedures.

5.1.3 coding and debugging
(1) Give a list of all source programs. The program is required to have sufficient annotation statements. At least the meaning of each function parameter and the meaning of the function return value should be annotated.

```#include <iostream>
#include <cstring>
using namespace std;
#define maxn 100005
#define M 105
int c[M] [maxn] ;	//c[i][j] represents the maximum value obtained by putting the first I items into a shopping cart with a capacity of j
int w[M] ,v[M] ;		//w[i] represents the weight of the ith article, and v[i] represents the value of the ith article
int x[M];			//x[i] indicates whether the ith item is put into the shopping cart
int main() {
int i,j,n,W;			//N represents n items and W represents the capacity of the shopping cart
cout << "Please enter the number of items n: ";
cin >> n;
cout << "Please enter the capacity of the shopping cart W: ";
cin >> W;
cout << "Please enter the weight of each item in turn w And value v，Separate with spaces: ";
for(i=1;i<=n;i++)
cin>>w[i]>>v[i];
for(i=0;i<=n;i++) 		//Initialize column 0 as 0
c[i] [0]=0;
for(j=0;j<=W;j++) 		//Initialize line 0
c[0] [j]=0;
for(i=1;i<= n;i++) 		//Calculation c[i] [j]
for(j=1;j<=W;j++)
if(j<w[i]) 		//When the weight of the item is greater than the capacity of the shopping cart, the item will not be placed
c[i][j] = c[i-1] [j] ;
else		//Otherwise, compare whether this item can maximize the value in the shopping cart
c[i] [j] = max(c[i-1][j],c[i-1] [j-w[i]] + v[i]) ;
cout<<"The maximum value loaded into the shopping cart is: "<<c[n] [W]<<endl;//Inverse construction of optimal solution
j=W;
for(i=n; i>0;i--)
if(c[i][j]>c[i-1] [j])
{
x[i]=1;
j-=w[i] ;
}
else
x[i]=0;
cout<<"The items loaded into the shopping cart are: ";
for(i=1;i<=n; i++)
if(x[i]==1)
cout<<i << " ";
return 0;
}
```

(2) Problems encountered in debugging the program and how to solve them,
(3) The time and space complexity of the algorithm is analyzed.
Time complexity: the main algorithm is a two-layer nested for loop, and its time complexity is O(nW).
Space complexity: because of the two-dimensional array c[n][W], the space complexity is O (n, w).

5.1.4 test and result analysis

5.1.5 algorithm optimization
First, there is a main loop i=1, 2,... N, which calculates all the values of the two-dimensional array c[i][0w] each time. Then, if only one array dp[0W] is used, can we ensure that the state represented in dp[i] is the State c[i][j] defined by us after the end of the i-th cycle? c[i] [] is recursively derived from two subproblems c[i-1]i] and c[i-1] [j-w []. Can we ensure that the values of c[i-1] [] and c[i-1][j-w[i] can be obtained when recursing c[i][i] (that is, when recursing dp[j] in the ith main cycle)? In fact, this requires j=W, W-1 dp[i] is pushed backward in the order of 1 and 0, so as to ensure that dp[i- c[i] saves the value of State c[i-1][j-w[i] when dp[j] is pushed.
The pseudo code is as follows:

```for i=1. .n
for j=W. .0
dp[j]=max{dp[j] ,dp[j-w[i]]+v[i]};
Among them, dp[i]=max {dp[i]，dp[i- w[i]}It's equivalent to the transfer equation c[i][j]=max{c[i -1][j]， c[i-1][j-w[]},Because here dp[j- w[i]It's equivalent to the original c[i-1][j- w[i]].
#include <iostream>
#include<cstring>
using namespace std;
#define maxn 10005
#define M 105
int dp [maxn] ;				//dp[j] represents the maximum value obtained by the shopping cart with capacity of j
int w[M],v[M]; 			//w[i] represents the weight of the ith article, and v[i] represents the value of the ith article
int x[M];					//x[i] indicates whether the ith item is put into the shopping cart
int i,i,n,W;				//N represents n items and W represents the capacity of the shopping cart
void opt1 (int n, int W)
{
for(i=1;i<=n;i++)
for(j=W;j>n;j--)
if(j>=w[i]) // When the capacity of the shopping cart is greater than or equal to the weight of the item, compare whether the item is placed or not
It can maximize the value in the shopping cart
dp[j] = max(dp[j],dp[j-w[i]]+v[i]) ;
}
int main()
{
cout << "Please enter the number of items n:";
cin >> n;
cout << "Please enter the capacity of the shopping cart w:";
cin >> W;
cout << "Please enter the weight of each item in turn w And value v,Separate with spaces:";
for(i=1; i<=n; i++)
cin>>W[i]>>v[i] ;
for(j=1;j<=W;j++)//Initialize line 0
dp[j]=0;
opt1 (n,W) ;
//opt2(n,W) ;
//opt3(n,W) ;
cout<<"The maximum value loaded into the shopping cart is: "<<dp[W]<<endl;
/ /test dp[]Array results
for(j=1;j<=W;j++)
cout<<dp[j]<<" ";
cout<<endl;
return 0;
}
```

In fact, we can narrow the scope, because it is updated only when the capacity of the shopping cart is greater than or equal to the weight of the item (dp[j]= max (dp[j],dp[j- w[i]+v[i]). If the capacity of the shopping cart is less than the weight of the item, the original value (phase) will be maintained
When it is the original c[i-1][j]). Therefore, the second for statement can be for (J = w; J > = w [i]; J –) without searching
Find j=0.

```void opt2(int n,int W)
{
for(i=1;i<= n;i++)
for (j=W;j>=w[i];j--)
//When the capacity of the shopping cart is greater than or equal to the weight of the item, compare whether this item can maximize the value in the shopping cart
dp[j] = max(dp[j] ,dp[j-w[i]]+v[i]) ;
}
We can also narrow the scope and determine the lower bound of the search bound,Search lower bound w[i]And the maximum remaining capacity,
sum[n] -sum[i- 1]express i~n The sum of the weight of the item. W- (sum[n] -sum[i- 1])Indicates the remaining capacity.
Because only when the shopping cart capacity exceeds the lower limit, it will be updated(dp[i] = max (dp[i], dp[j- w[i]]+v[i]))，If
If the shopping cart capacity is less than the lower bound, the original value will be maintained(Equivalent to the original c[i-1][j)Just. So the second for language
The sentence can be for(j=W; j>=bound; j--)， Without having to search j=0.
void opt3(int n, int W)
{
int sum[n];//sum[i] represents the sum of the weights of articles from 1 to I
sum[0]=0;
for (i=l;i<=n; i++)
sum[i]=sum[i-1] +W[i] ;
for (i=1; i<=n;i++)
{
int bound=max (w[i],W- (sum [n]-sum[i-1]));//Search lower bound, w[i] and residual capacity
Maximum, sum[n]-sum[i-1]Indicates from i...n Sum of the weight of the articles
for (j=w;j>=bound;j--)
//The shopping cart capacity is greater than or equal to the lower bound. Compare whether this item can maximize the value in the shopping cart
dp[j] = max(dp[j],dp[j-w[i]]+v[i]);
}
}
```

## 5.2 backtracking method

5.2.1 analyze the problem, model the problem, and select the appropriate data structure according to the model.
(1) Define the solution space of the problem
The shopping cart problem belongs to a typical 0-1 knapsack problem. The solution of the problem is to select some items from n items so that they are not,
Maximum value in excess of capacity. Each item has only two states, either loaded into the shopping cart or not loaded.
So can the i-th item be loaded into the shopping cart to meet the target requirements, or can it not be loaded into the shopping cart to meet the target requirements?
Obviously, it's not sure yet. Therefore, the variable x can be used; Indicates whether the i-th item is loaded into the shopping cart. If "0" indicates that it is not loaded into the backpack and "1" indicates that it is loaded into the backpack, then x; The value of is 0 or 1. i=1, 2,... N the ith item is loaded into the shopping cart, x=1; Do not load shopping cart, x=0. The solution of the problem is an n-tuple, and the value of each component is 0 or 1.
Thus, the solution space of the problem is {x, x2,. xi,..., xn}, where the explicit constraint xi= 0 or 1, i=1,
2，...， n.
(2) Determine the organizational structure of solution space
The solution space of the problem describes two "possible solutions, which can also be said to be the number of all subsets of a set composed of n elements. For example, for the shopping cart problem of three items, the solution space is: {0, 0, 0}, {0, 0, 1}, {0, 1, 0}, {0, 1, 1}, {1,0, 0}, {1, 0, 1}, {1, 1,0}, {1, 1,1}. There are 23 possible solutions to this problem.
It can be seen that the solution space tree of the problem is a subset tree, and the depth of the solution space tree is the scale n of the problem, as shown in Figure 5-5.

(3) Search solution space
constraint condition
The solution space of the shopping cart problem contains 2^n possible solutions. There are some or some items that cannot be loaded into the shopping cart. Therefore, it is necessary to set constraints to judge whether the total weight of the items loaded into the shopping cart exceeds the capacity of the shopping cart. If so, it is an infeasible solution; Otherwise, it is a feasible solution. The search process no longer searches the nodes and their child nodes that lead to infeasible solutions.
The constraints are:

scope condition
There may be more than one feasible solution to the shopping cart problem. The goal of the problem is to find an item loaded into the shopping cart with the maximum total value
The feasible solution is the optimal solution. Therefore, it is necessary to set the limit conditions to speed up the speed of finding the optimal solution. According to the organizational structure of the solution space, for any intermediate node z (intermediate state), the state represented by the branch from the root node to the z node (whether to load the shopping cart or not) has been determined, and the state of the branch from z to its descendant node is uncertain. That is, if the level of z in the solution space tree is t, the state of the first article to the t-1 article has been determined. We just need to expand along the branch of z to easily determine the state of the t-th item. Then the state of the first t items is determined. However, the status of items t+1 to n is uncertain. In this way, after the status of the first t items is determined, the total value of the items currently loaded into the shopping cart is expressed in cp. The high value of loaded items is not necessarily optimal, because there are still undetermined remaining items. We are not sure about the actual state of items t+1 to N, so we can only use the estimated value. Assuming that items t+1 to n are loaded into the shopping cart, the total value of items t+1 to n is expressed by rp, so cp+rp is the upper bound of the value of all feasible solutions starting from the root and passing through the intermediate node z, as shown in Figure 5-6.

If the value upper bound is less than or equal to the currently searched optimal value (the optimal value is represented by bestp and the initial value is 0), then
It shows that it is impossible to obtain a better feasible solution than the current one by continuing the search from the intermediate node z to the descendant node
On the contrary, continue to search for the descendant nodes of z.
The gauge conditions are:
cp+rp>bestp
search process
Start from the root node and search in a depth first manner. The root node first becomes a live node, which is also the current extension
Node. Since the value on the left branch of the subset tree is agreed to be "1", extending along the left branch of the extension node means loading articles. At this time, it is necessary to judge whether the item can be loaded, that is, whether the constraint condition is true or not. If it is true, the left child node will be generated. The left child node will become a live node and become the current expansion node, and continue to expand to the depth node;
If not, cut off the left branch of the extension node and expand along its right branch. The right branch represents that the items are not loaded into the shopping cart,
It must lead to feasible solutions. But is it possible to get the optimal solution by extending along the right branch? This needs to be determined by the gauge
Conditions. If the bound condition is satisfied, it may lead to the optimal solution, that is, generate the right child node and the right child node
Become a live node, and become the current expansion node, and continue to expand to the depth node; If the gauge conditions are not met, cut it off
Expand the right branch of the node and trace back to the nearest ancestor living node. The search process ends when all live nodes become dead nodes.

5.2.2 detailed design
(1) Storage structure type definition of each abstract data type.
(2) Algorithm idea and pseudo code: describe the design idea of the algorithm to solve the corresponding problem, and design the corresponding pseudo code.
a. Computational upper bound
Calculating the upper bound refers to calculating the sum of the value cp of the loaded items and the total value rp of the remaining items. We already know the value cp of the items loaded into the shopping cart. We are not sure what to load for the remaining items. We estimate it according to the assumption that they are loaded, that is, it is calculated according to the maximum value (the total value of the remaining items), so the value obtained is the upper bound of the value of the items that can be loaded.

```double Bound(int i)//Calculate the upper bound (i.e. the value of loaded items + the total value of remaining items)
{
int rp=0; //The remaining items are the i~n items
while(i<=n) //Calculate the value of the remaining items in turn
{
rp+=v[i] ;
i ++;
}
}
```

(2) Search and solve according to constraint conditions and clearance conditions
t indicates that the current extension node is at layer t, cw indicates the weight of the currently placed items, and cp indicates the value of the currently placed items.
If t > N, it means that the leaf node has been reached. Record the optimal value and return the optimal solution. Otherwise, judge whether the constraint conditions are met, and if so, search the left subtree. Because the left subtree indicates that the item is put in, x[t]=1 indicates that the t-th item is put in. cw+=w[t], indicating that the weight of the currently placed articles increases by w[t]. cp+=v[t], indicating that the value of the currently placed items has increased by v[t]. Backtrack(t+1) means recursive, depth first search layer t+1. When regressing, that is, when backtracking upward, subtract the increased value, cw-=w[t], cp- =v[t].
Judge whether the limit conditions are met, and search the right subtree if they are met. Because the right subtree indicates that the item is not put in, let x[t]=0. The weight and value of the currently placed items will not change. Backtrack(t+1) means recursive, depth first search layer t+1.

```void Backtrack(int t)		//T indicates that the current extension node is at layer t

{
if (t>n)		//The leaf node has been reached
{
for(j=1;j<=n;j++)
{
bestx[j]=x[j];
}
bestp=cp;		//Save current optimal solution
return ;
}
if (cw+w[t]<=W) 		//If the constraints are met, the left subtree is searched
{
x[t]=1;
CW+=w[t] ;
cp+=v[t] ;
Backtrack(t+1) ;
CW-=W[t] ;
cp-=v[t] ;
}
if (Bound(t+1) >bestp) // If the bound condition is satisfied, the right subtree is searched
{
x[t]=0;
Backtrack(t+1) ;
}
}
```

(3) Draw the call diagram of functions and procedures.

5.2.3 coding and debugging
(1) Give a list of all source programs. The program is required to have sufficient annotation statements. At least the meaning of each function parameter and the meaning of the function return value should be annotated.

```#include <iostream>
#include <string>
#include <algorithm>
#define M 105
using namespace std;
int i,j,n,W;				//N represents n items and W represents the capacity of the shopping cart
double w[M],v[M];			//w[i] represents the weight of the ith article, and v{i] represents the value of the ith article
bool x[M] ;					//x[i] indicates whether the ith item is put into the shopping cart
double cw; 					//Current weight
double cp;					//Current value
double bestp;				//Current optimal value
bool bestx [M] ;			//Current optimal solution
double Bound(int i)			//Calculate the upper bound (i.e. the total value of the remaining items)
{
//The remaining items are i~n items:
int rp=0;
while(i<=n)				//Load items in descending order of value per unit weight
{
rp+=v[i] ;
i++;
}
return cp+rp;
}

void Backtrack(int t)		//Used to search the number of spaces. T indicates that the current extension node is at layer t
{
if(t>n)//The leaf node has been reached
{
for(j=1;j<=n;j++)
{
bestx[j]=x[j];	//Save current optimal solution
}
bestp=cp;			//Save current optimal value
return ;
}
if (cw+w[t]<=W)			//If the constraints are met, the left subtree is searched
{
x[t]=1;
cw+=w[t] ;
cp+=v[t] ;
Backtrack(t+1) ;
cw-=w[t] ;
cp-=v[t] ;
}
if (Bound(t+1) >bestp)	 //If the constraints are met, the right subtree is searched
{
x[t]=0;
Backtrack(t+1) ;
}
}

void Knapsack (double W,int n){
//initialization
cw=0;					//Initialize that the weight of the items currently placed in the shopping cart is 0
cp=0;					//Initialize the value of the item currently placed in the shopping cart to 0
bestp=0;				//The current optimal value of initialization is 0
double sumw=0.0; 		//Used to count the total weight of all items
double sumv=0.0; 		//Used to calculate the total value of all items
for(i=1; i<=n; i++)
{
sumv+=v[i] ;
sumw+=w[i] ;
}
if (sumw<=W)
{
bestp=sumv;
cout<<"The maximum value of items put into the shopping cart is: "<<bestp<<endl;
cout<<"All items are put in the shopping cart.";
return;
}
Backtrack(1) ;
cout<<"The maximum value of items put into the shopping cart is: "<<bestp<<endl;
cout<<"The item number put into the shopping cart is: ";
for(i=1;i<=n;i++) 		//Output optimal solution
{
if (bestx[i]==1)
cout<<i<<" ";
}
cout<<endl;
}

int main()
{
cout << "Please enter the number of items n: ";
cin >> n;
cout << "Please enter the capacity of the shopping cart w: ";
cin >> W;
cout << "Please enter the weight of each item in turn w And value v，Separate with spaces: ";
for(i=1;i<=n; i++)
cin>>w[i]>>v[i] ;
Knapsack(W,n) ;
return 0;
}
```

(2) Problems encountered in debugging the program and how to solve them,
(3) The time and space complexity of the algorithm is analyzed.
a time complexity
The running time of backtracking method depends on the number of nodes it generates in the search process. The bound function can greatly reduce the number of generated nodes, avoid invalid search and speed up the search speed. The left child needs to judge the constraint function and the right child needs to judge the bound function. How many left children and right children are there in the worst case? Let's look at the subset tree with scale n. the worst-case state is shown in Figure 5-17.

The total number of nodes is 20 + 2 +... + 2 "= 2"+l-1. Subtract the tree root node and divide by 2 to get the number of left and right child nodes. The number of left and right child nodes = (2 + 1-1-1) / 2 = 2 "- 1.
The time complexity of constraint function is 0 (1), and the time complexity of bound function is O(n). In the worst case, 0 (2 ") left child nodes call the constraint function and 0 (2") right child nodes need to call the bound function. Therefore, the time complexity of the backtracking method to solve the shopping cart problem is 0(12"+n2")=O(n*2 ").
b space complexity
Another important feature of backtracking method is to generate solution space while searching. At any time in the search process, only the path from the start node to the current extension node is reserved, and the longest path from the start node is n. In the program, we use the bestp [] array to record the longest path as the optimal solution, so the spatial complexity of the algorithm is O(n).

5.2.4. Test and result analysis

5.2.5 algorithm optimization
In the above program, the upper bound function is the sum of the current value cp and the total value rp of the remaining items. This valuation is too high, because the weight of the remaining items is likely to exceed the capacity of the shopping cart. Therefore, we can narrow the upper bound, so as to speed up the pruning speed and improve the search efficiency.
Upper bound function bound(): the current value cp + the maximum value brp of the remaining items that can be accommodated by the remaining capacity.
In order to better calculate and use the upper bound function pruning, the article is first pruned according to its unit weight value (value / weight)
Sort from large to small, and then examine each item in the sorted order.

```#include <iostream>
#include <string>
#include <algorithm>
#define M 105
using namespace std;
int i,j,n,W;		//n represents the number of items and W represents the capacity of the shopping cart
double w[M]v[M]; 		//w[i] represents the weight of the ith article, and v[i] represents the value of the ith article
bool x[M];			//x[i]=1 indicates that the ith item is put into the shopping cart
double Cw;		//Current weight
double cp;			//Current value
double bestp; .		//Current optimal value
bool bestx[M] ;		//Current optimal solution
double Bound(int i)//Calculate the upper bound (that is, the maximum value that can be obtained when the remaining items are filled with the remaining Backpack Capacity)
{
//The remaining items are the i~n items
double cleft=W-cw; 	/ /Residual capacity
double brp=0.0;
while(i<=n &&W[i]<cleft)
{
cleft-=w[i] ;
brp+=v[i];
i++;
}
if(i<=n) 			//Fill the backpack by cutting. Here is the upper bound. Cutting is not allowed when solving
{
brp+=v[i]/w[i] *cleft;
}
return cp+brp;
}
void Backtrack(int t)					//Used to search the number of spaces. T indicates that the current extension node is at layer t
{
if(t>n) //The leaf node has been reached
{
for(j=1;j<=n;j++)
{
bestx[j]=x[j] ;
}
bestp=cp; 					//Save current optimal solution
return ;
}
if (Cw+w[t]<=W) 						//If the constraints are met, the left subtree is searched
{
x[t]=1;
cw+=w[t] ;
cp+=v[t] ;
Backtrack(t+1) ;
cw-=w[t] ;
cp-=v[t];
}
if (Bound(t+1) >bestp)				 //If the constraints are met, the right subtree is searched
{
x[t]=0; .
Backtrack(t+1) ;
}
}
struct Object				//Define the item structure, including item serial number and unit weight value
int id;					//Item serial number
double d;					//Unit weight value
};
bool cmp (Object al, object a2)		 //Sort according to the value per unit weight of items from large to small
{
return al.d>a2.d;
}
void Knapsack(int W，int n)
{
/ /initialization
cw=0;			//Initialize that the weight of the items currently placed in the shopping cart is 0
cp=0;				//Initialize the value of the item currently placed in the shopping cart to 0
bestp=0;				//The current optimal value of initialization is 0
double sumw=0;		//Used to count the total weight of all items
double sumv=0;		//Used to calculate the total value of all items
object Q[n];			//Item structure type, used to sort by unit weight value (value / weight ratio)
double a [n+1],b[n+1]; //Auxiliary array, used to transfer the sorted weight and value to the original weight value array
for (i=1; i<=n;i++)
{
Q[i-1] . id=i;
Q[i-1] . .d=1.0*v[i]/w[i];
sumv+=v[i] ;
sumw+=w[i] ;
}
if (sumw<=W)
{
bestp=sumv;
cout<<"The maximum value of items put into the shopping cart is: "<<bestp<<end1;
cout<<"All items are put in the shopping cart. ";
return;
}
sort (Q, Q+n,cmp); // Sort by unit weight value (value / weight ratio) from large to small
for (i=1; i<=n; i++)
{
a[i]=w[Q[i-1] .id];//Pass the sorted data to the auxiliary array
b[i]=v[Q[i-1] .id] ;
}
for (i=l;i<=n;i++)
{
w[i]=a[i];				/ /Pass the sorted data to w[i]
V[i]=b[i];
}
Backtrack(1) ;
cout<< "The maximum value of items put into the shopping cart is: "<<bestp<<endl;
cout<<"The item number put into the shopping cart is: ";
for(i=1; i<=n; i++)
{
if (bestx[i]==1)
cout<<Q[i-1].id<<" ";
}
cout<<endl;
}
int main ()
{
cout<< "Please enter the number of items n:";
cin)>)>n;
cout << "Please enter the capacity of the shopping cart w:";
cin >> W;
cout << "Please enter the weight of each item in turn w And value v,Separate with spaces:";
for(i=1;i<=n;i++)
cin>>w[i]>>v[i] ;
Knapsack(W,n) ;
return 0;
}
```

(1) Time complexity:
The time complexity of constraint function is 0 (1), and the time complexity of bound function is O(n) In the worst case, 0(2n) left child nodes call the constraint function, 0(2n) right child nodes need to call the bound function, and the calculation time of Backtrack algorithm is O(n2^n). The time complexity of the sorting function is O(nlogn), which is the worst case. In fact, after the optimization of the upper bound function, the pruning speed is very fast, and there is no need to generate all nodes at all.
(2) Space complexity:
In addition to recording the optimal solution array, a structure array is also used for sorting, and two auxiliary arrays are used
Helper arrays pass the sorted results. The size of these arrays is n, so the space complexity is still O(n).

# 6. Summary and experience

Pay attention to the official account: I am TIME0101.