贪心算法之背包问题
贪心算法:
是指在对问题求解时做出在当前看来是最好的解,不从整体上考虑,换句话说就是局部最优解
基本思路:
1.数学模型描述问题
2.把求解的问题分为若干子问题
3.对每对子问题求解,得到局部最优解
4.再从局部最优解中找出整体最优解
算法实现:
实例:背包问题(可切割)
问题描述:有一个背包容量m=150,有7个物品,物品可以分割成任意大小,要求尽可能让装入背包的物品总价值最大,但不能超过总容量
物品:A B C D E F G
重量: 35 30 60 50 40 20 25
价值: 10 40 30 50 35 40 30
(1)根据贪心的策略,每次挑选价值最大的物品装入背包
(2)每次挑选所占重量最小的物品装入是否能得到最优解
(3)每次选取单位重量价值最大的物品
代码实现:
import java.util.Arrays;
public class GreedyP {
int packag_c = 150;
public int[] w = new int[]{35,30,60,50,40,10,25};
public int[] val = new int[]{10,40,30,50,35,40,30};
public static void main(String[] args){
GreedyP g = new GreedyP();
g.packageGreedy(g.packag_c,g.w,g.val);
}
private void packageGreedy(int c,int[] w,int[] val){//c表示容量
int n = w.length;
double[] r = new double[n]; //性价比数组,即单位质量的物品价格
int[] index = new int[n]; //性价比排序物品的下标
for(int i = 0;i < n;i++){
r[i] = (double) val[i] / w[i];
index[i] = i;
}
double temp = 0; //对性价比进行排序
for(int i = 0;i < n - 1;i++){
for(int j = i + 1;j < n;j++){
if(r[i] < r[j]){
temp = r[i];
r[i] = r[j];
r[j] = temp;
int x = index[i];
index[i] = index[j];
index[j] = x;
}
}
}
//将排序好的重量和价值分别存到数组中
int[] w1 = new int[n];
int[] value1 = new int[n];
for(int i = 0;i < n;i++){
w1[i] = w[index[i]];
value1[i] = val[index[i]];
}
int[] x = new int[n];
int maxValue = 0;
for(int i = 0;i < n;i++){
if(w1[i] <= c){ //表明还可以装得下
x[i] = 1;
c = c - w1[i];
maxValue += value1[i];
}
}
System.out.println("包中放下的物品数量:" + Arrays.toString(x));
System.out.println("最大价值为:" + maxValue);
}
}
参考资料:
算法设计与分析(第4版)