0-1背包问题
2015-10-19 22:32
232 查看
#include "cstdio" #include "queue" #define MAX 20 #define INF 999 using namespace std; int n; //物品数量 float w[MAX]; //物品重量数组 float c; //背包容量 float nowc; //当前背包内物品重量 float nowp; //当前背包内物品价值 int x[MAX]; //解向量 float bestp = 0; struct Item { float weight; //重量 float value; //价值 float vDw; //单位重量价值 }; int cmp(const void *item1, const void *item2) //按单位重量价值降序 { if((*(Item *)item1).vDw < (*(Item *)item2).vDw) return 1; else return 0; } Item item[MAX]; struct Node { float upvalue; //价值上界 int level; //结点所在层 float cp; //当前价值 float cw; //当前重量 //按价值上界建立优先队列,价值上界大的结点先出队列 bool operator < (const Node &nod) const { if(upvalue > nod.upvalue) return 1; else return 0; } }; priority_queue<Node> pq; void EnQueue(float upv, float cp, float cw, int le) { Node node; node.upvalue = upv; node.level = le; node.cp = cp; node.cw = cw; pq.push(node); } //计算结点所相应价值的上界 float bound(int i) { float cleft = c - nowc; //背包剩余容量 float nowv = nowp; //当前背包内物品价值 int j; //以物品单位重量价值递减序装剩余容量 while(i<n && item[i].weight<=cleft) //如果该物品还装得进去 { cleft -= item[i].weight; //剩余容量减少 nowv += item[i].value; //当前背包内物品价值增加 i++; } if(i<n) //将背包填满 nowv += (item[i].value / item[i].weight * cleft); return nowv; } float maxKnapsack() { Node node; //扩展结点 nowc = 0; //当前背包内物品重量 nowp = 0; //当前背包内所装物品价值 int i = 0; //当前结点所在层 float up = bound(0); //计算上界 while(i!=n) { if(nowc + item[i].weight <= c)//如果当前物品还装得进去,搜索左子树 { if(nowp+item[i].value > bestp) //更改最优价值 bestp = nowp+item[i].value; EnQueue(up, nowp+item[i].value, nowc+item[i].weight, i+1);//入队列 x[i] = 1; } up = bound(i+1); //计算上界 if(up >= bestp) //如果上界不小于当前最优价值,可能产生最优价值,搜索右子树 { EnQueue(up, nowp, nowc, i+1);//入队列 x[i] = 0; } node = pq.top(); //取下一个扩展结点 pq.pop(); nowc = node.cw; nowp = node.cp; i = node.level; } return bestp; } float knapsack(float weight[], float value[], int n1, int c1) { n = n1; c = c1; int i; for(i=0; i<n; i++) { item[i].weight = weight[i]; item[i].value = value[i]; item[i].vDw = value[i]/weight[i]; } qsort(item, n, sizeof(Item), cmp); return maxKnapsack(); } int main() { float c1 = 30; int n1 = 3; float weight[] = {16, 15, 15}; float value[] = {45, 25, 25}; float sum = knapsack(weight, value, n1, c1); printf("背包容量为:%.1f\n", c); printf("物品为(重量,价值):\n"); int i; for(i=0; i<n; i++) printf("(%.1f, %.1f)\t", item[i].weight, item[i].value); printf("\n"); printf("背包内所装物品的最大价值为:%.1f\n", sum); printf("最优解为:\n"); for(i=0; i<n; i++) printf("%d ", x[i]); printf("\n"); return 0; }
相关文章推荐
- Java记录 -41- IDE开发工具
- ORA- 12012 : err or on aut o execu te of job ORACLE_OCM. MGMT_CONFIG_JOB_2_1 ORA-29280: inval
- ocp-513
- UITextField
- Hibernate三种状态
- BNUOJ 1038 Flowers
- Sublime Text 全程指引 by Lucida
- 指数型母函数(转)
- ocp-512
- ocp-511
- easyUI datagrid 跨行跨列操作
- Android使用百度地图SDK
- 【特种兵Word教程】如何给Word 2013添加页眉页脚?
- ftp测试练习
- Linux下如何为刚安装好的Eclipse在桌面建一个启动图标?
- oracle之子查询、连接查询、递归查询
- [C++] any number to binary (Bit manipulation)
- Python深入:Distutils发布Python模块
- Linux操作系统中,*.zip、*.tar、*.tar.gz、*.tar.bz2、*.tar.xz、*.jar、*.7z等格式的压缩与解压
- finally的执行