贪心算法解决背包问题

题目

用贪心算法实现背包问题的求解。背包容量为20;最优解为装入背包的物品价值总和最大。

 

基本思想:

  •  计算所有物品的性价比
  • 按物品性价比从高到低装入,只有当高一级的性价比物品全部装入后,才会装入下一级的性价比物品。
  • 装到最后无法全部装入该物品时进行部分装入

代码结果:

 

代码如下: 

package algorism4;

public class GreedyBag {// 贪心算法解决的背包问题是可以部分装载的问题,不是0-1
	static float maxV = 20;// 最大容量
	float V;// 体积
	float worth;// 价值
	int i;// 物品编号
	float cost;// 性价比,单位体积价值
	static GreedyBag[] thing = new GreedyBag[6];// 根据实际情况调整
	static float[] x = new float[thing.length];// 物品i对应的数量在下标i-1

	public GreedyBag(int num, float V, float w) {// 物品信息初始化
		i = num;
		worth = w;
		this.V = V;
		cost = w / V;
		thing[i - 1] = this;// 添加进数组
	}

	public static void sort() {// 初始化满了再用的冒泡排序,性价比最小的沉底
		float smaller;// 存储更小的价值比
		for (int i = 0; i < thing.length; i++) {
			for (int j = 0; j < thing.length - i - 1; j++) {
				smaller = thing[j].cost;
				if (smaller < thing[j + 1].cost) {// 后面更大就交换
					GreedyBag bigger = thing[j + 1];
					thing[j + 1] = thing[j];
					thing[j] = bigger;
				}
			}
		}
	}

	public static float knapsack() {
		float maxValue = 0;
		float v = 0;// 已装载体积
		int i;
		for (int j = 0; j < x.length; j++)
			x[j] = 0;// 物品的装载初始化为0
		for (i = 0; i < thing.length; i++) {
			if (v + thing[i].V > maxV)
				break;// 下标i的物品没法全部装下
			x[thing[i].i - 1] = thing[i].V;// 性价比高的全部装下
			v += thing[i].V;
			maxValue += thing[i].worth;
		}
		if (i < thing.length) {// 由break跳出的,部分装载
			float elseV = maxV - v;
			x[thing[i].i - 1] = elseV;// 部分装载
			v = maxV;
			maxValue += elseV / thing[i].V * thing[i].worth;
		}
		return maxValue;
	}

	public static void printX() {// 打印装载情况
		for (int i = 0; i < x.length; i++) {
			if (x[i] == 0)
				continue;
			System.out.println("物品编号" + (i + 1) + "装了体积" + x[i]);
		}
	}

	public static void main(String args[]) {
		GreedyBag i1 = new GreedyBag(1, 3, 6);
		GreedyBag i2 = new GreedyBag(2, 2, 5);
		GreedyBag i3 = new GreedyBag(3, 5, 10);
		GreedyBag i4 = new GreedyBag(4, 1, 2);
		GreedyBag i5 = new GreedyBag(5, 6, 16);
		GreedyBag i6 = new GreedyBag(6, 4, 8);
		sort();// 根据性价比排序
		float maxValue = knapsack();
		System.out.println("最大能装价值" + maxValue + "的物品");
		printX();

	}

}

  • 0
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值