背包问题

来源:互联网 发布:四川省旅游 2016 数据 编辑:程序博客网 时间:2024/06/12 20:32
    我们有n种物品,物品j的重量为wj,价格为pj。我们假定所有物品的重量和价格都是非负的。背包所能承受的最大重量为W。    如果限定每种物品只能选择0个或1个,则问题称为0-1背包问题。各类复杂的背包问题总可以变换为简单的0-1背包问题进行求解。    有N件物品和一个容量为V的背包。第i件物品的重量是w[i],价值是v[i]。求解将哪些物品装入背包可使这些物品的重量总和不超过    背包容量,且价值总和最大。    这是最基础的背包问题,特点是:每种物品仅有一件,可以选择放或不放。用子问题定义状态:即f[i][v]表示前i件物品恰放入    一个容量为v的背包可以获得的最大价值。则其状态转移方程便是:    f[i][v]=max{ f[i-1][v], f[i-1][v-w[i]]+v[i] }。    可以压缩空间,f[v]=max{f[v],f[v-w[i]]+v[i]}    这个方程非常重要,基本上所有跟背包相关的问题的方程都是由它衍生出来的。所以有必要将它详细解释一下:“将前i件物品放入    容量为v的背包中”这个子问题,若只考虑第i件物品的策略(放或不放),那么就可以转化为一个只牵扯前i-1件物品的问题。    如果不放第i件物品,那么问题就转化为“前i-1件物品放入容量为v的背包中”,价值为f[i-1][v];如果放第i件物品,那么问题    就转化为“前i-1件物品放入剩下的容量为v-w[i]的背包中”,此时能获得的最大价值就是f [i-1][v-w[i]]再加上通过放入第i件    物品获得的价值v[i]。    注意f[v]有意义当且仅当存在一个前i件物品的子集,其费用总和为f[v]。所以按照这个方程递推完毕后,最终的答案并不一定    是f[N] [V],而是f[N][0..V]的最大值。如果将状态的定义中的“恰”字去掉,在转移方程中就要再加入一项f[v-1],这样就可以    保证f[N] [V]就是最后的答案。    背包问题(Knapsack problem)是一种组合优化的NP完全问题。问题可以描述为:给定一组物品,每种物品都有自己的重量和价格,    在限定的总重量内,我们如何选择,才能使得物品的总价格最高。   在01背包问题中,在选择是否要把一个物品加到背包中,必须把该物品加进去的子问题的解与不取该物品的子问题的解进行比较,   这种方式形成的问题导致了许多重叠子问题,使用动态规划来解决。n=5是物品的数量,c=10是书包能承受的重量,w=[2,2,6,5,4]是   每个物品的重量,v=[6,3,5,4,6]是每个物品的价值,先把递归的定义写出来    然后自底向上实现,代码如下:
import numpy as npdef bag(w,v,c,n):    opt=np.zeros((n,c+1))    for j in range(c+1):        if j>=w[0]:            opt[0][j]=v[0]    for i in range(1,n):        for j in range(c+1):            if j>=w[i]:                opt[i][j]=max(opt[i-1][j-w[i]]+v[i], opt[i-1][j])            else:                opt[i][j]=opt[i-1][j]    return opt.astype(np.int)def find_position(w,c,n,opt):    print '最大价值为',opt[n-1][c]    t=[False for i in range(n)]    i=n-1; j=c    while i>=1:        while j>=0:            if opt[i][j]>opt[i-1][j]:                t[i]=True                print '第'+str(i)+'个'                j=j-w[i]                i=i-1                break            else:                i=i-1    if opt[i][j]>0:        t[i]=True        print '第'+str(i)+'个'    return tif __name__=='__main__':    w=[2,2,6,5,4]    v=[6,3,5,4,6]    c=10    n=5         opt=bag(w,v,c,n)      find_position(w,c,n,opt)
0 0