0-1 knapsack backtracking algorithm [suitable for Xiaobai, with analysis + annotation]
Title: using backtracking algorithm to realize 0-1 knapsack, the volume of knapsack is 7
Pack 4 items, the value of which is 9,10,7,4 respectively, and the weight of which is 3,5,2,1 respectively. Please use the backtracking method to realize the maximum value that a backpack can hold?
Analysis:
The so-called 0-1 knapsack, in order to maximize the value, considers whether the current item is loaded or not [only in these two cases, and the knapsack problem can only contain the part of the item], and the solution space can be represented by the number of subsets.
The backtracking method for solving 0-1 knapsack problem is similar to the backtracking method for loading problem. When searching the solution space tree, as long as the left child node is a feasible node, the search will enter the left subtree, and only when the right subtree contains a better solution will enter the right subtree, otherwise the right subtree will be cut off.
This is the key to the problem. How to cut off the right subtree: we can design an upper bound function. Only when the value returned by the upper bound function is greater than the current optimal value, can we enter the right subtree (that is, I don't load the current item, but load the next item, and get a higher price value)
Upper bound function: arrange the items in descending order of unit weight value, and load them in turn [this is to get an upper bound value, but in fact, it can't be retrieved, so when the items can't be put down, we can take part of the load, which is similar to the knapsack problem]
Therefore, the value, weight and unit value attributes of an item are stored in a structure. Most of the processing time of this method is here. In fact, backtracking is very simple. It is mainly for oj submission. It is directly programmed according to the data given by the topic. If you just want to practice backtracking, you can calculate the unit weight value of an item in advance, and then array the value and weight according to the item In descending order of unit weight value of
//1 the right subtree may contain the optimal solution before entering the right subtree, otherwise the right subtree will be subtracted //2 set r as the sum of current residual value cp as the best value of current value //The upper bound function calculates the upper bound value of items in descending order of unit value according to the knapsack problem #include<iostream> #include<algorithm> #include<cmath> #include<cstring> using namespace std; #define N 4 struct node{//Building an array of nodes int p;//value int w;//weight double per;//Average value }s[N]; int P[4]={9,10,7,4};//Value of goods int W[4]={3,5,2,1};//Weight of items double Per[4]; int c=7;//Capacity of backpack int cw;//Current weight int cp;//Current value int bestp=0;//Current optimal value //Exchange function void swap(int i,int j){//The structure stores data, so it can't be exchanged directly. It can only exchange each attribute one by one int a,b; double c; a=s[i].p; s[i].p=s[j].p; s[j].p=a; b=s[i].w; s[i].w=s[j].w; s[j].w=b; c=s[i].per; s[i].per=s[j].per; s[j].per=c; } void f(){//Calculate the average weight value of the item for(int i=0;i<N;i++){ s[i].p=P[i]; s[i].w=W[i]; s[i].per=P[i]*1.0/W[i]; } } void sort(){//Bubble sort for(int i=0;i<N;i++){ for(int j=0;j<N-i;j++){ if(s[j].per<s[j+1].per){ swap(j,j+1); } } } } int Bound(int i){//The function of calculating the upper bound int cleft=c-cw;//Residual capacity int b=cp;//Store current value while(i<N&&s[i].w<cleft){ cleft-=s[i].w; b+=s[i].p; } if(i<N){ b+=s[i].p*(cleft/s[i].w); } } void dfs(int i){//Core backtracking algorithm if(i>N){ bestp=cp; return; } if(cw+s[i].w<c){ //Less than the capacity of the backpack indicates that it can continue to load cw+=s[i].w; cp+=s[i].p; dfs(i+1); cw-=s[i].w; cp-=s[i].p; } if(Bound(i+1)>bestp){ //Plus the next value is greater than the current value, which means that the next value is better without the current value dfs(i+1); } } void display(){//Show that the output function can not be used just to check whether the data output is correct for(int i=0;i<N;i++){ cout<<"p"<<s[i].p<<endl; cout<<"w"<<s[i].w<<endl; cout<<"per"<<s[i].per<<endl; } } int main(){ f(); // Cout < before sorting < endl; // display(); // sort(); // Cout < after sorting < endl; // display(); // cout<<"jk"<<endl; dfs(0); cout<<"The optimal value is:"<<bestp<<endl; }