《分别用回溯法和分支限界法求解0-1背包问题》由会员分享,可在线阅读,更多相关《分别用回溯法和分支限界法求解0-1背包问题(8页珍藏版)》请在金锄头文库上搜索。
1、第 页 共 页一、 实验题目:分别用回溯法和分支限界法求解分别用回溯法和分支限界法求解 0-1 背包问题背包问题二、 实验内容:0-1 背包问题:背包问题: 给定给定 n 种物品和一个背包。物品种物品和一个背包。物品 i 的重量是的重量是 Wi,其价值为,其价值为 Vi,背包的容量为,背包的容量为 C。应如何选择装入背包的物品,使得装入背包中物品的总价值最大应如何选择装入背包的物品,使得装入背包中物品的总价值最大?在选择装入背包的物品时,对每种物品在选择装入背包的物品时,对每种物品 i 只有只有 2 种选择,即装入背包或不装入背包。不能将物品种选择,即装入背包或不装入背包。不能将物品 i 装入
2、装入背包多次,也不能只装入部分的物品背包多次,也不能只装入部分的物品 i。三、 程序源代码:A:回溯法:/ bag1.cpp : Defines the entry point for the console application. /#include “stdafx.h“ #include #define MaxSize 100 /最多物品数 int limitw; /限制的总重量 int maxwv=0; /存放最优解的总价值int maxw; int n; /实际物品数 int optionMaxSize; / 存放最终解 int opMaxSize; /存放临时解struct int
3、 weight;int value;aMaxSize; /存放物品数组 void Knap( int i, int tw, int tv) /考虑第 i 个物品 int j;if(i=n) /找到一个叶子结点 if (twmaxwv) /找到一个满足条件地更优解,保存它 maxwv=tv; maxw=tw;for(j=0;j#include#define MaxSize 100 /最多结点数typedef struct QNode float weight;float value;int ceng;struct QNode *parent;bool leftChild;QNode,*qnode
4、; /存放每个结点typedef struct qnode QMaxSize; int front,rear;SqQueue; /存放结点的队列SqQueue sq;float bestv=0; /最优解int n=0; /实际物品数float wMaxSize; /物品的重量float vMaxSize;/物品的价值int bestxMaxSize; / 存放最优解qnode bestE;void InitQueue(SqQueue sq.rear=1;第 页 共 页bool QueueEmpty(SqQueue sq) /队列是否为空if(sq.front=sq.rear)return t
5、rue;else return false;void EnQueue(SqQueue return ;sq.Qsq.rear=b;sq.rear=(sq.rear+1)%MaxSize;qnode DeQueue(SqQueue if(sq.front=sq.rear)printf(“队列已空!“);return 0;e=sq.Qsq.front;sq.front=(sq.front+1)%MaxSize;return e;第 页 共 页void EnQueue1(float wt,float vt, int i ,QNode *parent, bool leftchild)qnode b;i
6、f (i=n) /可行叶子结点if (vt=bestv)bestE=parent;bestxn=(leftchild)?1:0;return;b=(qnode)malloc(sizeof(QNode); /非叶子结点b-weight=wt;b-value=vt;b-ceng=i;b-parent=parent; b-leftChild=leftchild; EnQueue(sq,b); void maxLoading(float w,float v,int c) float wt=0;float vt=0;int i=1; /当前的扩展结点所在的层float ew=0; /扩展节点所相应的当前
7、载重量float ev=0; /扩展结点所相应的价值qnode e=NULL;qnode t=NULL;第 页 共 页InitQueue(sq);EnQueue(sq,t); /空标志进队列while (!QueueEmpty(sq) wt=ew+wi; vt=ev+vi;if (wt bestv) bestv=vt;EnQueue1(wt,vt,i,e,true); / 左儿子结点进队列 EnQueue1(ew,ev,i,e,false); /右儿子总是可行;e=DeQueue(sq); / 取下一扩展结点if (e = NULL)if (QueueEmpty(sq) break;EnQue
8、ue(sq,NULL); / 同层结点尾部标志e=DeQueue(sq); / 取下一扩展结点i+;ew=e-weight; /更新当前扩展结点的值ev=e-value;printf(“最优取法为:n“);for( int j=n-1;j0;j-) /构造最优解bestxj=(bestE-leftChild?1:0);bestE=bestE-parent;第 页 共 页for(int k=1;k=n;k+)if(bestxk=1)printf(“n 物品%d:重量:%.1f,价值:%.1fn“,k,wk,vk);printf(“n“);printf(“最优价值为:%.1fnn“,bestv);void main()int c;float ewvMaxSize;printf(“ -0-1 背包问题分枝限界法-nn“);printf(“请输入物品的数量:n“);scanf(“%d“,printf(“请输入背包的最大承重量:n“);scanf(“%d“,printf(“n 请输入物品的重量和单位重量价值:nn“);for(int i=1;i=n;i+)printf(“物品%d:“,i);scanf(“%f%f“,vi=wi*ewvi;printf(“n“);maxLoading(w, v, c);第 页 共 页分支限界法测试结果: