【贪心策略】背包问题

问题描述:

给定n个物体(它们的重量为:w1,w2,......,wn,价值为:v1,v2,......,vn) 和 一个承受重量为W的背包,每种物体都可以分割。问怎么选取这些物体,放在的背包中(不超过背包的承重),让所取的子集达到最大价值。

贪心策略:

优先选取性价比最高的物体,也就是 vi/wi 最高的第 i 个物体。当然也有其他的策略,比如优先取 vi 最高的物体、优先取 wi 最低的物体从而尽可能存放更多的东西。

步骤设计:

1)对所有物体按照 vi/wi 进行排序,初始化最大价值maxValue = 0

2)如果背包还有容量的话(W > 0),首选比值较大的物体(vi,wi)。

若背包剩余容量W ≥ 比值最大的物体的总容量wi,则将物体(vi,wi)整个放入背包、W=W-wi、maxValue=maxValue+vi;

若背包剩余容量W < wi,则将剩下的空间都放入物体(vi,wi)的一部分、W=0、maxValue=maxValue+W / wi * vi。

代码实现:

// 贪心策略

public class PkgProblemTest {
	public static void main(String[] args) {
		double[] w = {7, 3, 4, 5};      // 物体的重量
		double[] v = {12, 12, 40, 25};  // 物体的价值
		int W = 10;   // 背包承重
		int n = 4;    // 物体个数
		
		// 排序
		for (int j=0; j<3; j++) {
			int max = j;
			for (int i=j+1; i<4; i++) {
				if ( v[i]/w[i] > v[max]/w[max] ) {
					max = i;
				}
			}
			
			if (max != j) {
				swap(v, max, j);
				swap(w, max, j);
			}
		}
		
		// 验证排序是否成功
		for (int i=0; i<4; i++) {
			System.out.print(v[i]/w[i] + "\t");
		}
		System.out.println();
		
		// 计算最大价值
		double maxValue = 0.0;
		while (W > 0) {
			for (int i=0; i<4; i++) {
				if (w[i] > W) {  // 代码出口
					maxValue += W/w[i] * v[i];
					W = 0;
					//break;
				} else {
					maxValue += v[i];
					W -= w[i];
				}
			}
		}
		
		System.out.println("最大价值为:" + maxValue);
		
	}
	

	// 交换数组两个下标对应的值
	public static void swap(double[] arr, int i, int j) {
		double tmp = arr[i];
		arr[i] = arr[j];
		arr[j] = tmp;
	}
}

运行结果如下所示,

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值