算法分析与设计--0/1背包问题(回溯法)

来源:互联网 发布:java中reflect 编辑:程序博客网 时间:2024/05/17 02:14
算法分析与设计--0/1背包问题(回溯法)
问题描述:

给定n种物品和一个容量为C的背包,物品i的重量是wi,其价值为vi,0/1背包问题是如何选择装入背包的物品(物品不可分割),使得装入背包中物品的总价值最大?


#include<iostream>using namespace std;const int n = 3;//物品个数const int C = 25;//背包容量int bestP = 0;//最大价值intw[n] = {20,15, 10};//物品重量intp[n] = {20,30, 25};//物品价值int cp = 0;//当前背包价值int cw = 0;//当前背包重量//w[n]存储物品的重量,p[n]存储价值//这个方法用来排序,单位价值由大到小void sortValue(int w[], int p[],int n){int index;int temp;//暂存变量for(int i = 0; i < n - 1; i++){index = i;for(int j = i + 1; j < n; j++){//单位重量价值的比较if((p[j] / w[j]) > (p[index] / w[index])){index = j;}}if(index != i) //交换记录,同时更新w和p数组{//交换价值记录temp = p[index];p[index] = p[i];p[i] = temp;//交换重量记录temp = w[index];w[index] = w[i];w[i] = temp;}}}int Bound(int i){    //计算节点所相应价值的上界    int cleft = C - cw;   //剩余容量    int b = cp;    //以物品单位重量价值递减顺序装入物品    while(i < n && w[i] <= cleft)    {        cleft -= w[i];        b += p[i];        i++;    }    if(i <= n)    {        b += p[i] * cleft / w[i];    }    return b;}//回溯求解0/1背包,寻找可行解void BackTrack(int i){if(i > n - 1){bestP = cp;return;}if(cw + w[i] <= C)//当前结点加上下一个结点的重量小于或等于总的背包容量{//进入左子树,也就是说w[i]被装入背包cw = cw + w[i];//背包当前的重量cp = cp + p[i];//当前获得的价值BackTrack(i + 1);//回溯,进入右子树cw = cw - w[i];cp = cp - p[i];}if(Bound(i+1) > bestP){BackTrack(i + 1);}}void putPackage(int w[],int p[]){BackTrack(0);//从根结点开始cout<<"背包的最大价值:"<<bestP<<endl;}int main(){for(int i = 0; i < n; i++){cout<<w[i]<<" ";}cout<<endl;for(int i = 0; i < n; i++){cout<<p[i]<<" ";}cout<<endl;putPackage(w,p);system("pause");return 0;}