贪心算法_01背包问题_Java实现
原文地址:http://blog.csdn.net/ljmingcom304/article/details/50310789
本文出自:【梁敬明的博客】
1.贪心算法
什么是贪心算法?是指在对问题进行求解时,总是做出当前看来是最好的选择。也就是说,不从整体最优上加以考虑,所得出的结果仅仅是某种意义上的局部最优解。因此贪心算法不会对所有问题都能得到整体最优解,但对于很多问题能产生整体最优解或整体最优解的近似解。
2背包问题
一个旅行者有一个最多能装m公斤的背包,现在有n中物品,每件的重量分别是W1、W2、……、Wn,每件物品的价值分别为C1、C2、……、Cn, 需要将物品放入背包中,要怎么样放才能保证背包中物品的总价值最大?
3.算法分析
当遇到这样的问题,我们可以换一种角度去思考,假设在一个100m3的房子里面,现在要将房子装满,同时要保证放入的物品个数最多以及装入的东西最重,现在身边有铁球和棉花,请问大家是放铁球进去好呢还是放棉花进去好呢?显而易见,放入铁球进去是最优选择。但是原因是什么呢?很简单,就是因为铁球的密度较大,相同体积的铁球和棉花相比,铁球更重。
不过前提是放入第一个铁球时,铁球的体积V1小于等于100m3 ;放入第二个铁球时,铁球的体积V2 小于等于(100-V1)m3;……;放入第n个铁球时,铁球的体积小于等于(100- ∑n1Vn-1)m3 ,要是第n个铁球的体积大于(100- ∑n1Vn-1)m3 ,还真是不如放点单位体积更轻的棉花进去,说的极端点就是所有铁球的体积都大于100m3 ,还真不如随便放入点棉花进去合算。所以总是放铁球进去,不考虑是否放入棉花,容易产生闲置空间,最终会得不到最优选择,可能只是最优选择的近似选择。
现在再次回到背包问题上,要使得背包中可以获得最大总价值的物品,参照铁球的例子我们可以知道选择单位重量下价值最高的物品放入为最优选择。但是由于物品不可分割,无法保证能将背包刚好装满,最后闲置的容量无法将单位重量价值更高的物品放入,此时要是可以将单位重量价值相对低的物品放入,反而会让背包的总价值和单位重量的价值更高。假设现在背包的剩余总重量为5kg,存在一个4kg价值为4.5的物品,一个3kg价值为3的物品,一个2kg价值为2的物品,很显然将3kg和2kg的物品放入背包中所获得的价值更高,虽然没有4kg的物品单位重量的价值高。因此通过贪心算法求解01背包的问题可能得不到问题的最优解,得到的是近似最优解的解。
创建一个物品对象,分别存在价值、重量以及单位重量价值三种属性。
public class Knapsack implements Comparable<Knapsack> {
/** 物品重量 */
private int weight;
/** 物品价值 */
private int value;
/** 单位重量价值 */
private int unitValue;
public Knapsack(int weight, int value) {
this.weight = weight;
this.value = value;
this.unitValue = (weight == 0) ? 0 : value / weight;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public int getUnitValue() {
return unitValue;
}
@Override
public int compareTo(Knapsack snapsack) {
int value = snapsack.unitValue;
if (unitValue > value)
return 1;
if (unitValue < value)
return -1;
return 0;
}
}
按照贪心算法将物品放入背包中。
public class TXSFProblem {
// 现有的物品
private Knapsack[] bags;
// 背包的总承重
private int totalWeight;
// 背包最大总价值
private int bestValue;
public TXSFProblem(Knapsack[] bags, int totalWeight) {
this.bags = bags;
this.totalWeight = totalWeight;
// 对背包按单位重量价值从大到小排序
Arrays.sort(bags, Collections.reverseOrder());
}
public void solve() {
int tempWeight = totalWeight;
for (int i = 0; i < bags.length; i++) {
//判断当前物品是否可以放入背包中,若不能则继续循环,查找下一个物品
if (tempWeight - bags[i].getWeight() < 0)
continue;
tempWeight -= bags[i].getWeight();
bestValue += bags[i].getValue();
}
}
public int getBestValue() {
return bestValue;
}
}
测试最终结果:85(实际最优结果为90)
public class TXSFTest {
public static void main(String[] args) {
Knapsack[] bags = new Knapsack[] { new Knapsack(2, 13),
new Knapsack(1, 10), new Knapsack(3, 24), new Knapsack(2, 15),
new Knapsack(4, 28), new Knapsack(5, 33), new Knapsack(3, 20),
new Knapsack(1, 8) };
int totalWeight = 12;
TXSFProblem problem = new TXSFProblem(bags, totalWeight);
problem.solve();
System.out.println(problem.getBestValue());
}
}
欢迎关注我的微信公众号:“”Java面试通关手册(坚持原创,分享美文,分享各种Java学习资源,面试题,以及企业级Java实战项目回复关键字免费领取):
贪心算法_01背包问题_Java实现的更多相关文章
- 回溯算法_01背包问题_Java实现
原文地址:http://blog.csdn.net/ljmingcom304/article/details/50314839 本文出自:[梁敬明的博客] 1.回溯算法 回溯算法也叫试探法,通俗的将就 ...
- 贪心算法or背包问题
贪心方法:总是对当前的问题作最好的选择,也就是局部寻优.最后得到整体最优. 应用:1:该问题可以通过“局部寻优”逐步过渡到“整体最优”.贪心选择性质与“动态规划”的主要差别. 2:最优子结构性质:某个 ...
- 动态规划_01背包问题_Java实现
原文地址:http://blog.csdn.net/ljmingcom304/article/details/50328141 本文出自:[梁敬明的博客] 1.动态规划 什么是动态规划?动态规划就是将 ...
- [C++] 贪心算法之活动安排、背包问题
一.贪心算法的基本思想 在求解过程中,依据某种贪心标准,从问题的初始状态出发,直接去求每一步的最优解,通过若干次的贪心选择,最终得出整个问题的最优解. 从贪心算法的定义可以看出,贪心算法不是从整体上考 ...
- js贪心算法---背包问题
/* * @param {Object} capacity 背包容量 6 * @param {Object} weights 物品重量 [2,3,4] * @param {Object} values ...
- 贪心算法(Greedy Algorithm)
参考: 五大常用算法之三:贪心算法 算法系列:贪心算法 贪心算法详解 从零开始学贪心算法 一.基本概念: 所谓贪心算法是指,在对问题求解时,总是做出在当前看来是最好的选择.也就是说,不从整体最优上加以 ...
- 剑指Offer——贪心算法
剑指Offer--贪心算法 一.基本概念 所谓贪心算法是指,在对问题求解时,总是做出在当前看来是最好的选择.也就是说,不从整体最优上加以考虑,他所做出的仅是在某种意义上的局部最优解.虽然贪心算法不能对 ...
- js算法初窥05(算法模式02-动态规划与贪心算法)
在前面的文章中(js算法初窥02(排序算法02-归并.快速以及堆排)我们学习了如何用分治法来实现归并排序,那么动态规划跟分治法有点类似,但是分治法是把问题分解成互相独立的子问题,最后组合它们的结果,而 ...
- Java 算法(一)贪心算法
Java 算法(一)贪心算法 数据结构与算法目录(https://www.cnblogs.com/binarylei/p/10115867.html) 一.贪心算法 什么是贪心算法?是指在对问题进行求 ...
随机推荐
- 一些Redis面试题
1. 使用Redis有哪些好处? (1) 速度快,因为数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1) (2) 支持丰富数据类型,支持string,li ...
- 第102天:CSS3实现立方体旋转
CSS3实现立方体旋转 <!DOCTYPE html> <html lang="en"> <head> <meta charset=&qu ...
- BZOJ 2007 海拔(平面图最小割转对偶图最短路)
首先注意到,把一个点的海拔定为>1的数是毫无意义的.实际上,可以转化为把这些点的海拔要么定为0,要么定为1. 其次,如果一个点周围的点的海拔没有和它相同的,那么这个点的海拔也是可以优化的,即把这 ...
- BZOJ 1264 基因匹配(DP+线段树)
很有意思的一道题啊. 求两个序列的最大公共子序列.保证每个序列中含有1-n各5个. 如果直接LCS显然是TLE的.该题与普通的LCS不同的是每个序列中含有1-n各5个. 考虑LCS的经典DP方程.dp ...
- [NOI2016]优秀的拆分 后缀数组
题面:洛谷 题解: 因为对于原串的每个长度不一定等于len的拆分而言,如果合法,它将只会被对应的子串统计贡献. 所以子串这个限制相当于是没有的. 所以我们只需要对于每个位置i求出f[i]表示以i为开头 ...
- 【BZOJ2141】排队(树套树)
[BZOJ2141]排队(树套树) 题面 BZOJ 洛谷 题解 傻逼题啊... 裸的树套树 树状数组套线段树,每次交换的时候,考虑一下前后的贡献,先删掉贡献,再重新算一遍就好了.. #include& ...
- 洛谷 P4503 [CTSC2014]企鹅QQ 解题报告
P4503 [CTSC2014]企鹅QQ 题目背景 PenguinQQ是中国最大.最具影响力的SNS(Social Networking Services)网站,以实名制为基础,为用户提供日志.群.即 ...
- 「CodePlus 2017 12 月赛」可做题2(矩阵快速幂+exgcd+二分)
昨天这题死活调不出来结果是一个地方没取模,凉凉. 首先有个一眼就能看出来的规律... 斐波那契数列满足$a_1, a_2, a_1+a_2, a_1+2a_2, 2a_1+3a_2, 3a_1+5a_ ...
- 【bzoj4543】Hotel加强版(thr)
Portal --> bzoj4543 Solution 一年前的题== 然而一年前我大概是在划水qwq 其实感觉好像关键是..设一个好的状态?然后..你要用一种十分优秀的方式快乐转移 ...
- cin/cout与scanf/printf的比较
转自http://www.cnblogs.com/penelope/articles/2426577.html cin .cout 基本说明: cin是标准输入流对象,代表标准输入设备(键盘), ...