回溯法解0-1背包问题

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

int main ()
{
    intvalue[MAX]  = {20,15,15,10,30,60}; //物品价值
    intvolume[MAX] = {3,6,5,2,4,8}; //物品体积
    itemite[MAX]; //保存物品信息
   makeItem (value,volume,ite);//将物品信息保存到结构体
    Init(); //初始化全局参数
    printf("采用回溯法解决背包问题\n");
   BacktrackPackage (ite,0); //调用回溯法解决背包问题
    display(value,volume); //输出结果
    return0;
}
//初始化全局参数
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
原创粉丝点击