zoukankan      html  css  js  c++  java
  • 0-1背包

    0-1 背包问题

    问题:

    ​ 给定一组商品和价值

    物品 体积 价格
    物品1 3 6
    物品2 4 7
    物品3 5 8
    物品4 6 9
    物品5 7 10

    ​ 现有背包20, 求拿的最高的价值。

    思考

    ​ * 每件物品有取和不取的选择。

    ​ * 所有问题都通过子问题求解(递归思想)

    ​ * 根据动态规划思维(将子问题结果存起来):

    ​ 问题拆分:

    ​ 1. 可以将 背包容量拆分

    ​ 2. 拆分物体个数

    ​ 得出以下图

    0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
    0
    物品1
    物品2
    物品3
    物品4
    物品5

    在不同体积下,不同个数的物品找最大值。

    创建列表: v[k][w] k 代表选[0 ---- k] 件商品, w代表背包容量

    例如: v[5][3] 在前5件商品中取出,背包容量为3的最大价值

    推出面对 第k件时有一下情况

    1. 背包容量不够

      ​ value_max = v[k-1][w] # 就是在 0----k-1 件中, 且背包容量为 w的最大价值

      1. 背包容量够

        1. 不取

        ​ value_max1 = v[k-1][w] # 就是在 0----k-1 件中, 且背包容量为 w的最大价值

        ​ value_max2 = v[k-1][w-kw] + Vw # 要查看 在 背包容量为 w - kw 的情况下 0 到 k-1件商品中最高价值 加上 当前商品的价值。 因为 要腾出容量存当前物体

        ​ 例如: 看容量20时,取第五件的价值需要:(5件商品 体积7 价值10)

        ​ 容量为 20 -1 = 13 时: 0-4 的最高价值 即 B[4][13]+ 10

      最终决定取不取就是 max(value_max1,value_max2 ) 看哪个大。

    代码实现:

    def get_max(cap):
        B = [[0 for i in range(cap+1)] for i in range(len(W))]
        for k in range(0, len(W)):  # 物品个数
            for w in range(0, cap+1): # 背包容量
                if W[k] > w: # 如果第n 个的体积大于背包容量
                    B[k][w] = B[k-1][w]  # 0-k 里最大价值就是 在背包容量为 w时 0 到 k-1 件商品内的最大价值
                else:  # B[k-1][w-W[k]] + V[k] 查看 在 背包容量为 w - kw 的情况下 0 到 k-1件商品中最高价值 加上 当前商品的价值。 因为 要腾出容量存当前物体
                    B[k][w] = max(B[k-1][w-W[k]] + V[k],   B[k-1][w])  # 应该时取和不取两种情况下的最大值
        return B[len(W)-1][cap], B
                    
    result, B = get_max(20)
    pprint.pprint(B)
    
    # 假如说我要知道有哪些物品, 如果  B[k][cap] == B[k-1][cap-W[k]] + V[k] 说明这件物品找到了, 接下来就应该看,容量为 cap-W[k] 背包的选物情况了。 不等于的话说明这件没取到, 就看下一件
    def get_items(cap, B):
        for k in range(len(W)-1, 0, -1):
            while cap > 0:
                if B[k][cap] == B[k-1][cap-W[k]] + V[k]:
                    # 说明第k件取到了
                    print(k)
                    cap = cap-W[k]
                break
            
    get_items(20, B)
    
    
  • 相关阅读:
    第二次冲刺(二)
    第二次冲刺(一)
    5月30日学习日志
    5月29日学习日志
    5月28日学习日志
    5月27日学习日志
    5月26日学习日志
    粒子群算法-PSO
    花授粉优化算法-python/matlab
    花授粉优化算法
  • 原文地址:https://www.cnblogs.com/ShanCe/p/15110029.html
Copyright © 2011-2022 走看看