题目:
用贪心算法实现背包问题的求解。背包容量为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();
}
}