0-1背包回溯

还是先用到贪心:按单位重量价值由大到小排序

限界函数:假定可以装入部分,算出把背包装满的价值,作为上界

回溯函数:判断完这一层返回上一层

代码实现:

  1 #include<iostream>
  2 using namespace std;
  3 int n;//物品数量 
  4 double c;//背包容量
  5 double v[100];//各个物品的价值
  6 double w[100];//各个物品的重量
  7 double cw = 0.0;//当前背包重量 
  8 double cp = 0.0;//当前背包中物品价值
  9 double bestp = 0.0;//当前最优价值
 10 double perp[100];//单位物品价值排序后
 11 int order[100];//物品编号
 12 int put[100];//设置物品是否装入 解空间向量
 13 
 14 //按单位价值排序
 15 void knapsack() 
 16 {
 17     int i,j;
 18     int temporder = 0;
 19     double temp = 0.0;
 20     for(i = 1;i <= n;i++)
 21         perp[i]=v[i]/w[i];
 22     for(i = 1;i<=n-1;i++)
 23     {
 24         for(j=i+1;j<=n;j++)
 25         {
 26             if(perp[i]<perp[j])//冒泡排序 
 27             {
 28                 temp = perp[i];
 29                 perp[i] = perp[j];
 30                 perp[j] = temp;
 31                 
 32                 temporder = order[i];
 33                 order[i] = order[j];
 34                 order[j] = temporder;
 35                 
 36                 temp = v[i];
 37                 v[i] = v[j];
 38                 v[j] = temp;
 39                 
 40                 temp = w[i];
 41                 w[i] = w[j];
 42                 w[j] = temp; 
 43             }
 44         }
 45     }
 46 }
 47 
 48 //回溯函数 
 49 void backtrack(int i)
 50 {
 51     double bound(int i);
 52     if(i>n)//到达最后一层,找到一个可行的解 
 53     {
 54         bestp = cp;
 55         return;
 56     }
 57     if(cw+w[i]<=c)//当前背包重量加上要放入的物品重量小于等于背包容量 
 58     {
 59         cw+=w[i];
 60         cp+=v[i];
 61         put[i]=1;
 62         backtrack(i+1);
 63         cw-=w[i];
 64         cp-=v[i]; 
 65     }
 66     if(bound(i+1)>bestp)//符合条件搜索右子树
 67         backtrack(i+1); 
 68 }
 69 
 70 //限界函数
 71 double bound(int i)
 72 {
 73     double leftw = c-cw;
 74     double b = cp;
 75     while(i<=n&&w[i]<=leftw)
 76     {
 77         leftw-=w[i];
 78         b+=v[i];
 79         i++;
 80     }
 81     if(i<=n)
 82         b+=v[i]/w[i]*leftw;
 83     return b;
 84  } 
 85  
 86  
 87 
 88 int main()
 89 {
 90     int i;
 91     cout<<"请输入物品的数量和背包的容量:"<<endl;
 92     cin>>n>>c;
 93     cout<<"请输入物品的重量和价值:"<<endl;
 94     for(i = 1 ; i <= n ; i++){
 95         cout<<""<<i<<"个物品的重量:"<<endl;
 96         cin>>w[i];
 97         cout<<""<<i<<"个物品的价值:"<<endl;
 98         cin>>v[i];
 99         order[i]=i; 
100     } 
101     knapsack(); 
102     backtrack(1);
103     cout<<"最大价值为:"<<bestp<<endl;
104     cout<<"需要装入的物品编号是:"<<endl;
105     for(i=1;i<=n;i++)
106     {
107         if(put[i]==1)
108             cout<<order[i]<<" ";
109      } 
110      return 0;
111 } 

 

posted on 2018-12-16 15:09  huangroumin  阅读(259)  评论(0编辑  收藏  举报

导航