回溯法解0-1背包问题

回溯法解背包问题///
算法思想:
  运用深度优先算法解决,并在计算过程中通过确定上限减少
  不必要的枝干计算。
使用结构体:
  item{int value;int volume;} //保存物品的价值与体积
  sqStack(item item;int top) //栈用于深度优先算法
函数说明:BacktrackPackage
  输入: item ite[] //物品信息
      int nextItem //下一个需要处理的物品编号
  输出:记录保存的物品最大价值与构成
算法思路:
    如果当前栈总价值比最大保存栈总价值更大,更新信息
  for each item                                    //对剩余物品遍历
    物品进栈
    if volume+ < MaxVol  && tag!=1 //当物品总体积小于最大体积并且未被读取
      BacktrackPackage next     //递归计算
///
#include
#define MAX 6
typedef struct
{
      int value; //物品价值
      int volume;  //物品体积
} item;
typedef struct
{
    item ite[MAX];  //保存物品信息
      int valueNow;//当前物品价值总和
      int volumeNow;//当前物品体积总和
      int top;
} SqStack;
typedef struct
{
      item ite[3*MAX];
      int front,rear;
} SqQueue;
SqStack s;      //处理用栈
SqStack saveMax; //保存最大价值物品组成
int maxVol;      //背包容量
void Init ();//初始化全局参数
void makeItem (int value[],int volume[],item ite[]);//将物品信息保存到结构体
void display (int value[],int volume[]);//结果输出
bool Push (item i);  //出栈
bool pop (item i);  //入栈
void BacktrackPackage (item ite[],int nextItem);

int main ()
{
      int value[MAX]  = {20,15,15,10,30,60}; //物品价值
      int volume[MAX] = {3,6,5,2,4,8}; //物品体积
      item ite[MAX]; //保存物品信息
      makeItem (value,volume,ite);//将物品信息保存到结构体
      Init ();  //初始化全局参数
      printf ("采用回溯法解决背包问题\n");
      BacktrackPackage (ite,0); //调用回溯法解决背包问题
      display (value,volume); //输出结果
      return 0;
}
//初始化全局参数
void Init ()
{
      maxVol = 21;
      s.top = -1;
      s.valueNow = 0;
      s.volumeNow = 0;
      saveMax.valueNow = 0;
}
//将物品信息保存到结构体
void makeItem (int value[],int volume[],item ite[])
{
      int i;
      for (i=0; i
      {
              ite[i].value = value[i];
              ite[i].volume = volume[i];
      }
}
//输出结果
void display (int value[],int volume[])
{
      int i;
      printf ("物品(价值,体积)组成为:");
      for (i=0; i
      {
              printf ("(%d,%d)",value[i],volume[i]);
      }
      printf ("\n背包最大容量为:%d\n",maxVol);
      printf ("最大价值为:%d\n组成为:",saveMax.valueNow);
      for (i=0; i<=saveMax.top; i++)
              printf ("(%d %d) ",saveMax.ite[i].value,saveMax.ite[i].volume);
      printf ("\n");
}
bool Push (item i)
{
      //printf ("出栈item=%d  %d\n\n",i.value,i.volume);
      s.top --;
      s.valueNow -= i.value;
      s.volumeNow -= i.volume;
}
bool pop (item i)
{
      //printf ("入栈item=%d  %d  ",i.value,i.volume);
      s.top ++;
      s.ite[s.top] = i;      //物品进栈
      s.valueNow += i.value;  //物品价值累计
      s.volumeNow += i.volume;//物品体积累计
}
void BacktrackPackage (item ite[],int nextItem)
{
      int i;
      if (s.valueNow > saveMax.valueNow)//判断当前总价值是否超过已经记录的最大价值
              saveMax = s;
      for (; nextItem<6; nextItem++)//对所有剩余物品检查
      {
              pop (ite[nextItem]);
              //printf ("当前总价值:%d总体积:%d\n",s.valueNow,s.volumeNow);
              //printf ("s.volumeNow=%d\n",s.volumeNow);
              if (s.volumeNow<=maxVol)//如果当前总体积加上下一物品体积小于最大体积
              {
                      //printf ("进入递归nextItem=%d\n",nextItem+1);
                      BacktrackPackage (ite,nextItem+1);//对下一物品递归
              }
              Push (ite[nextItem]); //递归返回出栈当前物品
      }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值