贪心算法——宝藏放背包问题(附java代码)

        贪心算法:在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的是在某种意义上的局部最优解。贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的选择,选择的贪心策略必须具备无后效性,即某个状态以前的过程不会影响以后的状态,只与当前状态有关。

        首先给出一个问题(背包问题),可以描述为:给定一组物品,每种物品都有自己的重量和价格,在限定的总重量内,我们如何选择,才能使得物品的总价格最高。

        这个问题贪心算法无法解决,这里主要借助这个问题讲贪心算法的思想。

        假定有6个物品,他的质量分别是{35,30,60,50,40,10,25}kg

        他们的价格分别是{10,40,30,50,35,40,30}元。

        如果只能带走150kg的东西,你应该如何选择?

        我们知道,可以通过性价比来进行判断。所以我们可以通过求出性价比,然后排序性价比,然后从性价比最大的开始选择,直到装满为止。这就是贪心算法的思路。

代码:

public class GreedyPackage {
	//定义最大负重,weight数组保存重量,values数组保存价值
	public int max_weight = 150;
	public static int[] weight = new int[] {35,30,60,50,40,10,25};
	public static int[] value = new int[] {10,40,30,50,35,40,30};
	//
	public void greedyPackage(int capacity, int[] weight , int[] value) {
		//性价比数组创建并排序
		int n = weight.length;//总个数
		double[] price = new double[n];//性价比数组
		int count[] = new int[n];//序号数组
		
		//求性价比
		for (int i = 0; i < n; i++) {
			price[i] = (double)value[i] / weight[i];
			count[i] = i;
		}
		
		//性价比排序
		for (int i = 0; i < n - 1; i++) {
			for (int j = i; j < n - 1; j++) {
				if (price[j] < price[j + 1]) {
					double tmp = price[j];
					price[j] = price[j + 1];
					price[j + 1] = tmp;
					//交换性价比排序后,再吧序号交换,方便之后取数
					int a = count[j];
					count[j] = count[j + 1];
					count[j + 1] = a;
				}
			}
		}
		
		//把质量和价值也按照性价比的排序顺序对应好,存到新数组里
		int newWeight[] = new int[n];
		int newValue[] = new int[n];
		for (int i = 0; i < n; i++) {
			newValue[i] = value[count[i]];
			newWeight[i] = weight[count[i]];
		}
		
		double maxValue = 0;
		//装东西,优先拿性价比高的
		for (int i = 0; i < n; i++) {
			if (capacity > newWeight[i]) {
				capacity -= newWeight[i];
				maxValue += newValue[i];
			}			
		}
		
		System.out.print("共放下了" + (max_weight - capacity) +"kg重的东西\n");
		System.out.print("总价值" + maxValue);
	}
	
	public static void main(String[] args) {
		GreedyPackage greedyPackage = new GreedyPackage();
		greedyPackage.greedyPackage(greedyPackage.max_weight, weight, value);
	}
}


        但是这仍然存在一个问题,不一定先选最大性价比,最后的总价值就能最多。

        比如重量为{16,10,10}kg的3个物品

        价值为{32,19,18},最多能拿20kg的物品的话,按照贪心算法,他会选择16kg的价值为32的,然后就放不下了。但是如果拿后面两个的话,总价值会高于第一种取法。这时如果想得到全部的最优解,我们就要用到动态规划解决这一题,详细请看:0-1背包问题(动态规划)。贪心算法同时适用于可拆分的物品,通过性价比排名就可以进行更好的选择。

你可能感兴趣的:(java算法学习)