1、实验五 01 背包问题一、 实验内容:运用分支限界法解决 0-1 背包问题。二、 算法分析分支限界法分支限界法按广度优先策略遍历问题的解空间树, 在遍历过程中, 对已经处理的每一个结点根据限界函数估算目标函数的可能取值, 从中选取使目标函数取得极值 的结点优先进行广度优先搜索, 从而不断调整搜索方向, 尽快找到问题的解。因为限界函数常常是基于问题的目标函数而确定的, 所以, 分支限界法适用于求解最优化问题。0-1背包问题1)基本思想给定 n 种物品和一个容量为 C 的背包, 物品 i 的重量是 Wi, 其价值为V i , 0/ 1 背包问题是如何选择装入背包的物品(物品不可分割) , 使得装入
2、背包中物品的总价值最大,一般情况下, 解空间树中第 i 层的每个结点 , 都代表了对物品1 i 做出的某种特定选择, 这个特定选择由从根结点到该结点的路径唯一确定: 左分支表示装入物品, 右分支表示不装入物品。对于第 i 层的某个结点, 假设背包中已装入物品的重量是 w, 获得的价值是 v, 计算该结点的目标函数上界的一个简单方法是把已经装入背包中的物品取得的价值 v, 加上背包剩余容量 W - w 与剩下物品的最大单位重量价值 vi + 1/ wi + 1的积,于是,得到限界函数:u b = v + ( W - w) ( vi + 1/ wi + 1 )根据限界函数确定目标函数的界 down
3、 , up,然后, 按照广度优先策略遍历问题的空间树。2)复杂度分析时间复杂度是O(2 n);三、 实验结果:四、源程序及注释:#include#include#include#include#includeusing namespace std;int *x;struct node /结点表结点数据结构node *parent,/父结点指针*next; /后继结点指针int level,/结点的层bag,/节点的解cw,/当前背包装载量 cp;/当前背包价值 float ub; /结点的上界值;class Knapprivate:struct node *front, /队列队首*bestp
4、,*first; /解结点、根结点int *p,*w,n,c,*M;/背包价值、重量、物品数、背包容量、记录大小顺序关系long lbestp;/背包容量最优解 public:void Sort();Knap(int *pp,int *ww,int cc,int nn);Knap();float Bound(int i,int cw,int cp);/计算上界限node *nnoder(node *pa,int ba,float uub);/生成一个结点 ba=1 生成左节点 ba=0 生成右节点void addnode(node *nod);/将结点添加到队列中void deletenode
5、(node *nod);/将结点队列中删除struct node *nextnode(); /取下一个void display(); /输出结果void solvebag(); /背包问题求解;Knap:Knap(int *pp,int *ww,int cc,int nn) int i;n=nn;c=cc;p=new intn;w=new intn;M=new intn;for(i=0;inext=NULL;lbestp=0;bestp=new node1;bestp=NULL;Sort();Knap:Knap()delete first;delete front;delete bestp;d
6、elete p;delete w;float Knap:Bound(int i,int cw,int cp)/ 计算上界int cleft=c-cw; float b=(float)cp; while (iparent=pa;nodell-next=NULL;nodell-level=(pa-level)+1;nodell-bag=ba;nodell-ub=uub;if(ba=1)nodell-cw=pa-cw+wpa-level;nodell-cp=pa-cp+ppa-level ;else nodell-cw=pa-cw;nodell-cp=pa-cp;return(nodell);voi
7、d Knap:addnode(node *no)/将结点加入优先队列node *p=front-next,*next1=front;float ub=no-ub;while(p!=NULL)if(p-ubnext=p;next1-next=no;break;next1=p;p=p-next;if(p=NULL)next1-next=no;node *Knap:nextnode()/取上限最大结点 node *p=front-next;front-next=p-next;return(p);void Knap:Sort()int i,j,k,kkl;float minl; for(i=1;i=1
8、;i-) xMi-1=bestp-bag;bestp=bestp-parent;coutparent=NULL;first-next=NULL;first-level=0;first-cw=0;first-cp=0;first-bag=0;ubb=Bound(0,0,0);first-ub=ubb;front-next=first;while(front-next!=NULL)aa=nextnode();i=aa-level;if(i=n-1) if(aa-cw+wicp+pi)lbestp)lbestp=aa-cp+pi;bestp=nnoder(aa,1,(float)lbestp);if
9、(long)(aa-cp)lbestp) lbestp=aa-cp;bestp=nnoder(aa,0,(float)lbestp);if(icw+wicw+wi,aa-cp+pi)(float)lbestp)ubb=Bound(i,aa-cw+wi,aa-cp+pi);addnode(nnoder(aa,1,ubb);ubb=ubb=Bound(i,aa-cw,aa-cp);if(ubblbestp)addnode(nnoder(aa,0,ubb);display();void main()int c,n;int i=0;int *p;int *w;coutc;coutn; x=new intn;p=new intn;w=new intn;coutwi; coutpi;x=new intn;Knap knbag(p,w,c,n);knbag.solvebag();getch();system(“pause“);return;