贪心算法之背包问题

贪心算法之背包问题


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.贪心解决背包问题步骤

贪心策略:每次选择单位重量价值最高的物品装入背包

  1. 计算每种物品单位重量的价值\(\frac {V_i} {W_i}\),按单位重量的价值从大到小将\(n\)中物品排序。
  2. 以排序后的次序依次将物品装入背包。直至全部物品都装入或者因背包容量不足不能装入为止
  3. 如果背包尚有容量,将最后不能完全装入物品切割一部分装满背包
  4. 算法结束

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];
}
posted @ 2020-12-16 22:03  Thoughtful_z  阅读(1709)  评论(0)    收藏  举报