贪心算法解决背包问题
2015-12-08 20:34
633 查看
问题重述:
与0-1背包问题类似,所不同的是,在选择物品i装入背包的时候,可以选择物品i的一部分装入背包,而不一定全部装入背包,这是与0-1背包问题的差别。形式化描述语言:给定背包容量c(c>0),和物品i的重量wi(wi>0)、价值vi(vi>0)。
要求找出一个n元向量(x1,x2,x3,...,xn),使得∑_(i=1)^n▒〖w_i
x_i 〗≤c∑_(i=1)^n▒〖v_i
x_i 〗
实例说明:
给定背包容量50Kg,物品信息:物品1,重量10Kg,价值60元;物品2,重量20Kg,价值100元;物品3,重量30Kg,价值120元。则贪心策略有三种:
1、先把价值高的装进去,这样来说,能够确保背包内物品价值的有效增长,但是背包容量消耗太快,不利于总体价值的最大化。
2、先把重量小的物品装进去,这种策略能确保背包内的空间得以有效的利用,但是背包内物品的价值却不能有效增长,即增长缓慢,也不利于总体价值的最大化。
3、以上两种策略只考虑到了背包价值的增长和背包容量的利用,都不利于背包内物品价值的最大化。不妨,给每件物品赋予权重=价值/重量,并且按照物品的权重降序排序,依次将物品装入背包。三种策略示意图如下:
代码和注释如下:
与0-1背包问题类似,所不同的是,在选择物品i装入背包的时候,可以选择物品i的一部分装入背包,而不一定全部装入背包,这是与0-1背包问题的差别。形式化描述语言:给定背包容量c(c>0),和物品i的重量wi(wi>0)、价值vi(vi>0)。
要求找出一个n元向量(x1,x2,x3,...,xn),使得∑_(i=1)^n▒〖w_i
x_i 〗≤c∑_(i=1)^n▒〖v_i
x_i 〗
实例说明:
给定背包容量50Kg,物品信息:物品1,重量10Kg,价值60元;物品2,重量20Kg,价值100元;物品3,重量30Kg,价值120元。则贪心策略有三种:
1、先把价值高的装进去,这样来说,能够确保背包内物品价值的有效增长,但是背包容量消耗太快,不利于总体价值的最大化。
2、先把重量小的物品装进去,这种策略能确保背包内的空间得以有效的利用,但是背包内物品的价值却不能有效增长,即增长缓慢,也不利于总体价值的最大化。
3、以上两种策略只考虑到了背包价值的增长和背包容量的利用,都不利于背包内物品价值的最大化。不妨,给每件物品赋予权重=价值/重量,并且按照物品的权重降序排序,依次将物品装入背包。三种策略示意图如下:
代码和注释如下:
#include <iostream> #include <algorithm> #define MAX_NUM 1000 using namespace std; struct Goods //info of goods定义物品信息结构体 { int weight;// the weight of goods重量 int value;// the value of goods价值 double ValPerWei;// value per weight权重 double load; //物品装入背包的部分的系数(例如上图中物品全部装入则load为1,装入10/20则load为0.5) }; int cmp( Goods const &a, Goods const &b)//定义sort函数的比较函数 { if(a.ValPerWei<b.ValPerWei) return 0; else return 1; } void Greedy(Goods g[],int good_num, int content)//贪心算法 { for(int i=0; i<good_num; i++) { if(content>g[i].weight)//如果背包足够装下整个物品 { content-=g[i].weight; g[i].load=1; } else if(content>0){//如果背包不足以装下整个物品 g[i].load=(double)content/g[i].weight;//计算物品装入背包的部分 content=0;//背包容量置0 return;//程序结束,返回 } } } int main() { int goods_num; int bagvol; double total_value=0; double total_weight=0; cout<<"Please input the volum of bag:"<<endl; cin>>bagvol; cout<<"Please input the number of goods:"<<endl; cin>>goods_num; Goods G[goods_num+1]; cout<<"Please inuput the weight and value of goods:"<<endl; for(int i=0; i<goods_num; i++) { cin>>G[i].weight>>G[i].value;//输入重量价值 G[i].ValPerWei=(double)G[i].value/G[i].weight;//计算权重 G[i].load=0;//load置0 } sort (G,G+goods_num,cmp);//sort by ValPerWei Greedy(G,goods_num,bagvol); cout<<"Info of loaded goods:"<<endl; for(int i=0;i<goods_num;i++)//output the info of goods { if(G[i].load==0.0)break;//如果检测到物品未被装入背包,则推出循环 total_value+=(G[i].value*G[i].load);//装入背包的物品总价值 total_weight+=(G[i].weight*G[i].load);//装入背包的物品总重量 cout<<"weight: "<<G[i].weight<<" "<<"value: "<<G[i].value<<" "<<"the value per weight of good: "<<G[i].ValPerWei<<" the part of goods: "<<G[i].load<<endl;//输出装入背包的物品信息 } cout<<"the volum of bag is: "<<bagvol<<endl;//输出背包容量 cout<<"the total weight is: "<<total_weight<<endl;//输出装入物品的总重量 cout<<"the total value is: "<<total_value<<endl;//输出装入物品的总价值 }
相关文章推荐
- 如何组织构建多文件 C 语言程序(二)
- 如何写好 C main 函数
- 使用 Libki 来管理公共用户访问计算机
- 微型计算机的始祖:Altair 8800
- 通过手机、电脑远程开关机,Windows和linux机手机,电脑相互控制
- 动易2006序列号破解算法公布
- Ruby实现的矩阵连乘算法
- C#插入法排序算法实例分析
- Lua和C语言的交互详解
- 超大数据量存储常用数据库分表分库算法总结
- C#数据结构与算法揭秘二
- C#冒泡法排序算法实例分析
- C#使用回溯法解决背包问题实例分析
- 算法练习之从String.indexOf的模拟实现开始
- C#算法之关于大牛生小牛的问题
- C#实现的算24点游戏算法实例分析
- 关于C语言中参数的传值问题
- 简要对比C语言中三个用于退出进程的函数
- 深入C++中API的问题详解
- 基于C语言string函数的详解