01分数背包

来源:互联网 发布:淘宝打假怎么赚钱 编辑:程序博客网 时间:2024/06/06 00:24

1.0-1问题 fractional knapsack

现在有m件物品,小偷有个最大承重为n的背包,单独的一件物品可拆分,求最后的可得的最大重量。

2.首先计算每个商品的单位价值,遵循贪心策略,小偷首先尽量多地拿走单位价值最高的商品,若该商品已经全部拿走而背包未满,将在剩余的商品中选择单位价值最高的拿走,以此类推,若剩余空间不够选择的商品全部拿走,则将剩余空间全部装上该商品的等重部分(即把该商品拿走与背包空间刚好相同的重量)。

Step1:首先计算每件商品的单位价值;

Step2:按照商品的单位价值从高到低排序;

Step3:依次按照单位价值从高到低选择商品,判断当前剩余空间能否全部装下该商品,若能则装下该商品,剩余空间减去该商品的空间,继续循环Step3,若不能,则把剩余空间装下该商品的等重部分,算法结束。

背包内物品的类:额外设计一个表示背包内物品的类是为了计算方便,并且在算法结束后可以知道每件物品往背包内所放的重量。

class Item implements Comparable<Item> {public String name;// 物品的名字public int weight;// 物品的重量public int value;// 物品的价值public double price;// 单位价值public double inputWeight;// 被放到背包中的重量public Item(String name, int weight, int value) {this.name = name;this.weight = weight;this.value = value;this.price = value/weight;}public int compareTo(Item vo) {return this.price >= vo.price ? -1 : 1;}public String getName() {return name;}public void setName(String name) {this.name = name;}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 double getPrice() {return price;}public void setPrice(double price) {this.price = price;}public double getInputWeight() {return inputWeight;}public void setInputWeight(double inputWeight) {this.inputWeight = inputWeight;}}


实现0-1分数背包的java代码:

/** * 解决0--1分数背包问题。 *  * @param list *            传进来的是m件物品 * @param m *            背包的最大重量 * @return 背包内所装物品的最大价值。 */public double fractionalKnapsack(ArrayList<Item> list,int m){double result = 0;//最后返回的价值/*首先计算每件商品的单位价值,按照商品的单位价值从高到低排序*/Collections.sort(list);int size = list.size();for(int i =0;i<size;i++){Item vo = list.get(i);if(m>=vo.getWeight()){//说明当前商品可以全部放进去m = m-vo.getWeight();result = result + vo.getValue();vo.setInputWeight(vo.getWeight());//设置该商品放到背包中的重量}else if(m>0){//可放到背包的最后一件商品需要拆分vo.setInputWeight(m);result = result + m*vo.getPrice();m = 0;}else{break;}}return result;}

例如求解某五件商品在背包承重为10 的时候可装的最大价值。

public static void main(String[] args){FractionalKnapsack test = new FractionalKnapsack();Item B0 = new Item("F",5,6);Item B1 = new Item("D",4,6);Item B2 = new Item("C",1,6);Item B3 = new Item("B",2,6);Item B4 = new Item("A",3,6);ArrayList<Item> list = new ArrayList<Item>();list.add(B0);list.add(B1);list.add(B2);list.add(B3);list.add(B4);/*求往背包承重为10的背包内可装的物品的最大价值*/double re = test.fractionalKnapsack(list, 10);System.out.println("往背包承重为10的背包内可装的物品的最大价值 re = "+re);System.out.println("依次选择的物品名称与放到背包内的重量");for(int i =0;i<list.size();i++){Item vo = list.get(i);System.out.println(vo.getName()+"  "+vo.getInputWeight());}}


代码执行结果如下:




0 0
原创粉丝点击