前端外刊评论 2018-04-11
问题描述:
0-1背包问题,部分背包问题(课本P229)
实验要求:
(1)实现0-1背包的动态规划算法求解
(2)实现部分背包的贪心算法求解
0-1背包问题代码:
public static void main(String[] args){
//获取物品个数,每个物品的重量和价值,以及背包容量
Scanner in1 = new Scanner(System.in);
System.out.println("请输入物品个数和背包容量:");
int num_goods = in1.nextInt();
int capacity = in1.nextInt();
System.out.println("请输入1-"+num_goods+"的物品重量和价值:");
int[] weight = new int[num_goods+1];
int[] value = new int[num_goods+1];
Scanner in2 = new Scanner(System.in);
for(int i = 1;i<=num_goods;i++){
weight[i] = in2.nextInt();
value[i] = in2.nextInt();
}
in1.close();
in2.close();
//动态规划
int[][] f = new int[num_goods+1][capacity+1]; //f[i][j]表示容量为j的背包前i个物品的总价值
for(int i = 1;i<=num_goods;i++){
for(int j = 1; j<=capacity; j++){
if(weight[i] > j){
f[i][j] = f[i-1][j];
}else {
int x = f[i-1][j];
int y = f[i-1][j-weight[i]] +value[i];
f[i][j] = x>y?x:y;
}
}
}
//输出结果
for(int i = 0;i<= num_goods;i++){
for(int j = 0;j<=capacity;j++){
System.out.print(f[i][j]+"\t");
if(j == capacity){
System.out.print("\n");
}
}
}
int j = capacity;
int total_value = 0;
int total_weight = 0;
for(int i = num_goods;i>=1;--i){
if(j>0){
if(j-weight[i] >=0){
if(f[i][j] == (f[i-1][j-weight[i]]+value[i])){
System.out.println("选取物品:"+i+"重量为:"+weight[i]+"价值为:"+value[i]);
j -= weight[i];
total_value += value[i];
total_weight += weight[i];
}
System.out.println("总价值为:"+total_value+"\t总重量为:"+total_weight);
}
}
}
}二:部分背包
public class Goods{
int weight;
int value;
float value_per_weight; //value/weight
float load; //占比系数
}
//快排
public static void QuickSort(Goods []A,int l,int r){
Goods temp;
int i = l;
int j = r;
if(l<r){
temp = A[i];
while(i != j){
while(i<j && A[j].value_per_weight <= temp.value_per_weight){
--j;
}
A[i] = A[j];
while(i<j && A[i].value_per_weight >= temp.value_per_weight){
++i;
}
A[j] = A[i];
}
A[i] = temp;
QuickSort(A, l, i-1);
QuickSort(A, i+1, r);
}
}
//贪心算法
public static void Greedy(Goods[] goods,int capacity,int num_goods){
for(int i = 0; i<num_goods; i++){
if(goods[i].weight<capacity){
capacity -= goods[i].weight;
goods[i].load = 1;
}else if(capacity>0){
goods[i].load = ((float)capacity/(float)goods[i].weight);
capacity = 0;
break;
}
}
}
public static void main(String[] args){
float total_value = 0 ;
float total_weight = 0;
//获取物品个数,每个物品的重量和价值,以及背包容量
Scanner in1 = new Scanner(System.in);
System.out.println("请输入物品个数和背包容量:");
int num_goods = in1.nextInt();
int capacity = in1.nextInt();
System.out.println("请输入1-"+num_goods+"的物品重量和价值:");
Goods[] goods = new Goods[num_goods];
Scanner in2 = new Scanner(System.in);
for(int i = 0;i<num_goods;i++){
goods[i] = new part_of_package_greedy().new Goods();;
goods[i].weight = in2.nextInt();
goods[i].value= in2.nextInt();
goods[i].value_per_weight = (goods[i].value)/(goods[i].weight);
}
in1.close();
in2.close();
QuickSort(goods,0,(num_goods-1));
//执行贪心算法
Greedy(goods, capacity, num_goods);
System.out.println("执行贪心算法求得部分背包解为:");
for(int i = 0;i<num_goods;i++){
System.out.println("重量为:"+goods[i].weight+"\t价值为:"+goods[i].value+"\t装载率为:"+goods[i].load);
total_value+=goods[i].value*goods[i].load;
total_weight+=goods[i].weight*goods[i].load;
}
System.out.println("背包容量:"+capacity+"\t背包装入重量:"+total_weight+"\t装入总价值:"+total_value);
}