程序员程序园数据结构和算法分析

算法—背包问题

2019-05-14  本文已影响34人  zidea
algorithm

什么是背包问题:给出一系列矩阵,各自有值和容量,目标是找出总值最大的集合。这个问题的限制是,总容量必须小于等于”背包“的容量。

其实背包问题是一个组合优化问题:
有一个固定大小能够装 10W 的包以及一组有价值和重量的物品,找到一个最佳解决方案来装总重量不超过 10 的总价值最大的方案。


背包问题

我们来分析一下解决的思路,有关物品是否放入,答案其实就两个放入不放入。我们先初始化几个变量

我们先用最简单递归来实现上面算法


代码
var weights = [3,4,5];
var values = [2,3,4];
// [[1,5],[2,3],[4,5],[2,3],[5,2]];

function knapSackWithResu(n,c){
    var result = 0, a, b;

    
    if(n == 0 || c == 0){
        result = 0;
    }else if(weights[n] > c){
        result = knapSackWithResu(n-1,c)
    }else{
        a = knapSackWithResu(n-1,c);
        b = values[n] + knapSackWithResu(n-1,c-weights[n]);
        result = a > b?a:b;
    }

    // console.log(result);
    return result;
}


问题

在上面的递归运算中同样存在着问题,就是重复运算的问题,我们需要在递归过程中将重复运算结果缓存起来以备用从而减少运算的重复来达到优化的目的。

function knapSack(n, c){
    var i, w, a, b, ks = [];

    for(i = 0; i <= n; i++){
        ks[i] = []
    }

    for(i = 0; i <= n; i++){
        for(w =0; w <= c; w++){
            
            if(i ==0 || w ==0){
                ks[i][w] = 0;
            }else if(weights[i-1] <= w){
                a = values[i-1] + ks[i-1][w - weights[i-1]];
                b = ks[i-1][w];
                ks[i][w] = (a > b) ? a:b;
            }else{
                ks[i][w] = ks[i-1][w];
            }
        }
    }

    return ks[n][c];
}

优化

感谢 cs dojo 分享图片
参考《javascript 数据结构与算法》

javascript
上一篇下一篇

猜你喜欢

热点阅读