贪心算法之背包问题
贪心算法之背包问题
1.与动态规划的区别
通过研究解决经典的组合优化问题,来说明二者的差别。即0-1背包问题与背包问题
-
0-1背包问题:给定\(n\)中物品和一个背包。物品\(i\)的重量为\(W_i\),其价值为\(V_i\),背包的容量为\(C\)。应如何选择装入背包的物品,使得装入背包中物品的总价值最大?对于每种物品\(i\)只有俩种选择,即装入背包或不装入背包
-
背包问题:与0-1背包问题类似,不同在于选择物品\(i\)装入背包时,可以选择物品\(i\)的一部分,而不一定要全部装入背包,\(1 \le i \le n\)。
这2类问题都具有最优子结构性质,极为相似。背包问题可以用贪心算法求最优解,0-1背包不能使用贪心求解。
2.贪心解决背包问题步骤
贪心策略:每次选择单位重量价值最高的物品装入背包
- 计算每种物品单位重量的价值\(\frac {V_i} {W_i}\),按单位重量的价值从大到小将\(n\)中物品排序。
- 以排序后的次序依次将物品装入背包。直至全部物品都装入或者因背包容量不足不能装入为止
- 如果背包尚有容量,将最后不能完全装入物品切割一部分装满背包
- 算法结束
3.代码实现
/**
* n 物品数
* M 背包容量
* v[] 物品价值数组
* w[] 物品重量数组
* x[] 保存最优解路径数组,为1则表示该物品完全装入,否则装入该物品的一部分
**/
void Knapsack(int n, float M, float v[], float w[], float x[]) {
// 按照物品单位重量的价值递减排序
Sort(n, v, w);
int i;
for (i = 1; i <= n; i++)
x[i] = 0;
float c = M;
for (i = 1; i <= n; i++) {
if (w[i] > c)
break;
x[i] = 1;
c -= w[i];
}
if (i <= n)
x[i] = c / w[i];
}