算法分析与设计2017-2-背包问题的贪心算法
来源:互联网 发布:马锐拉的池塘 知乎 编辑:程序博客网 时间:2024/06/05 16:08
算法knapsack的主要计算时间在于将各种物品依其单位重量的价值从大到小排序。因此,算法的计算时间上界为O(nlogn)。为了证明算法的正确性,还必须证明背包问题具有贪心选择性质。这种贪心选择策略对0-1 背包问题就不适用了。看下图例子,其中有3中物品,背包的容量为50千克。物品1重10千克;价值60元;物品2重20千克;价值100元;物品3重30千克,价值120元。因此,物品1每千克价值6元,物品2每千克价值5元,物品3每千克价值4元。若依贪心选择策略,应首先选择物品1装入背包,然而从图b中各种情况可以看出,最优的选择方案是选择物品2和物品3装入背包。首选物品1的两种方案都不是最优的。对于背包问题,贪心选择最终可得到最优解,其选择方案如图c所示。
对于0-1背包问题,贪心选择之所以不能得到最优解是因为在这种情况下,它无法保证最终能将背包装满,部分闲置的背包空间使每公斤背包空间的价值降低了。事实上,在考虑0-1背包问题时,应比较选择该物品和不选择该物品所导致的最终方案,然后再作出最好选择。由此就导出许多互相重叠的子问题。这正是该问题可用动态规划算法求解的另一重要特征。
代码如下:
#include <stdio.h> #include <iostream> #include<algorithm> using namespace std; #define N 1000 struct bag{ int w;//物品的重量 int v;//物品的价值 double c;//物品的性价比 }a[1001]; bool cmp(bag a,bag b) { return a.c>=b.c; } double backpack(int n,bag a[],double c)//n表示物品的数量,a表示按照物品性价比排序后的数组,c表示剩余空间 { double cleft=c; int i=0; double b=0;//获得的价值 //当物品i可以装入背包中 while(i<n&&a[i].w<c) { c=c-a[i].w; b+=a[i].v; i++; } //说明物品不能完全装入背包 if(i<n) b+=1.0*a[i].v*c/a[i].w ; return b; } int main() { int c; int n; int i; printf("请输入物品的容量:\n"); scanf("%d",&c); printf("请输入每个物品的数量:\n"); scanf("%d",&n); printf("请输入每个物品的重量,价值:\n"); for(i=0; i<n; i++) { cin>>a[i].w>>a[i].v; a[i].c = 1.0*a[i].v/a[i].w; } sort(a, a+n, cmp);//按照性价比排序 printf("输出贪心算法最优解:\n"); cout<<backpack(n,a,c); return 0; }
运行效果:
参考博客 0022算法笔记——【贪心算法】背包问题,最优装载问题
我的个人博客网站
0 0
- 算法分析与设计-15-背包问题的贪心算法
- 算法分析与设计2017-2-背包问题的贪心算法
- 算法设计与分析 普通背包 贪心
- 【算法设计与分析基础】背包问题
- 算法设计的背包问题-------------用贪心算法求解
- 0-1背包问题的多种算法设计与分析
- 背包问题的贪心算法
- 背包问题的贪心算法
- 贪心算法-背包问题2
- 贪心算法 - 背包问题
- 贪心算法----背包问题
- 【贪心算法】:背包问题
- 贪心算法-背包问题
- 贪心算法 背包问题
- 贪心算法-背包问题
- 【贪心算法】背包问题
- 贪心算法-背包问题
- 贪心算法--背包问题
- IOCP在WSARecv出现10054错误以后,ACCEPT假死的问题
- 调整Eclipse字体大小
- 关于php的foreach
- amazeUI的icon图标库
- 【个人笔记重点,不作为参考】主题:js数组
- 算法分析与设计2017-2-背包问题的贪心算法
- CGI输出中文乱码解决方法
- 基于位运算插值的,easyX多按键检测<类>
- Java集合类 —— 集合类概述
- 随机
- Catalan数——卡特兰数
- MYSQL企业常用架构与调优经验分享
- vue中v-model动态生成
- linux进程的创建及使用