回溯算法---0-1背包问题

给定一个物品集合s={1,2,3,…,n},物品i的重量是wi,其价值是vi,背包的容量为W,即最大载重量不超过W。在限定的总重量W内,我们如何选择物品,才能使得物品的总价值最大。

0-1背包问题回溯算法的数据结构
#define NUM 100
int c; //背包的容量
int n; //物品的数量
int cw; //当前重量
int cv; //当前价值
int bestv; //当前最优价值
//描述每个物品的数据结构
struct Object{
int w; //物品的重量
int v; //物品的价值
double d; //物品的单位重量价值比
}Q[NUM]; //物品的数组

0-1背包问题回溯算法的实现

//形参i是回溯的深度,从0开始.商品编号从0开始编号
void backtrack(int i){
  if (i+1>n) {bestv = cv; return;}
  //进入左子树搜索, 表示选择第i件物品 
  if (cw+Q[i].w<=c){ //约束条件
      cw += Q[i].w;   //选择第i件物品 ,导致相关的数据发生变化
    cv += Q[i].v;	 //选择第i件物品 ,导致相关的数据发生变化
    backtrack(i+1);
    cw -= Q[i].w;	 //回溯的需要,恢复数据
    cv -= Q[i].v;	 //回溯的需要,恢复数据
  }
  //进入右子树搜索,表示不选择第i件物品,相关的cw, cv不改变
  if (Bound(i+1)>bestv) backtrack(i+1);
}

限界函数Bound()的实现

//形参i是回溯的深度
int Bound(int i){
  int cleft = c-cw;   //背包剩余的容量
  int b = cv;      //上界
  //尽量装满背包
  while (i<n && Q[i].w<=cleft){
    cleft -= Q[i].w;
    b += Q[i].v;
    i++;
  }
  //剩余的部分空间也装满。0-1是可能装不满的。但此处主要计算最大值,所以,需要从装满的角度考虑该问题
  if (i<n) b += 1.0*cleft*Q[i].v/Q[i].w;
  return b;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值