回溯法:0-1背包问题

 [转]http://fuliang.iteye.com/blog/165308

0-1背包问题:给定n种物品和一背包.物品i的重量是wi, 其价值为ui,背包的容量为C.
问如何选择装入背包的物品,使得装入背包中物品的总价值最大?
分析:
0-1背包是子集合选取问题,一般情况下0-1背包是个NP问题.
第一步 确定解空间:装入哪几种物品
第二步 确定易于搜索的解空间结构:
可以用数组p,w分别表示各个物品价值和重量。
用数组x记录,是否选种物品
第三步 以深度优先的方式搜索解空间,并在搜索的过程中剪枝
我们同样可以使用子集合问题的框架来写我们的代码,和前面子集和数问题相差无几。

 

#include<iostream>
#include<algorithm>
using namespace std;

class Knapsack{
public:
 Knapsack(double *pp,double *ww,int nn,double cc){
    p = pp;
    w = ww;
    n = nn;
    c = cc;
    cw = 0;
    cp = 0;
    bestp = 0;
    x = new int[n];
    cx = new int[n];
 }

 void knapsack(){
    backtrack(0);
  }

 void backtrack(int i){//回溯法
  if(i > n){
      if(cp > bestp){
         bestp = cp;
         for(int i = 0; i < n; i++)
    x[i] = cx[i];
      }
      return;
  }

  if(cw + w[i] <= c){//搜索右子树
    cw += w[i];
    cp += p[i];
    cx[i] = 1;
    backtrack(i+1);
    cw -= w[i];
    cp -= p[i];
  }
  cx[i] = 0;
  backtrack(i+1);//搜索左子树
 }

 void printResult(){
    cout << "可以装入的最大价值为:" << bestp << endl;
    cout << "装入的物品依次为:";
    for(int i = 0; i < n; i++){
      if(x[i] == 1)
    cout << i+1 << " ";
    }
    cout << endl;
 }

private:
   double *p,*w;
   int n;
   double c;
   double bestp,cp,cw;//最大价值,当前价值,当前重量
   int *x,*cx;
};

int main(){
  double p[4] = {9,10,7,4},w[4] = {3,5,2,1};
    Knapsack ks = Knapsack(p,w,4,7);
    ks.knapsack();
  ks.printResult();
  return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值