算法分析-动态规划-求解0-1背包问题

一.题目需求

 使用一个体积大小为13的背包,选择一件或多件商品带走,使得所选商品总价值最大。

商品列表如下:

 二.算法思想

1,这是一个经典的0-1背包问题

它要求我们在一组物品中选择一些,每个物品只能选择一次或者不选择,目标是使得所选物品的总价值最大。
这个问题在实际生活中有很多应用,比如旅行行李打包、资源分配等。本文将深入探讨0-1背包问题的算法分析。

2,0-1背包问题的基本定义
假设我们有n个物品和一个容量为V的背包,每个物品i有一个价值vi和一个重量wi。
我们的目标是在不超过背包容量的情况下,选择一些物品使得总价值最大。这就是0-1背包问题的定义。

3,解决这个问题的一种常见方法是动态规划

动态规划是一种通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。
对于0-1背包问题,我们可以定义一个二维数组dp[i][j],表示前i个物品中选择一些物品放入容量为j的背包可以获得的最大价值。
然后,我们可以通过比较物品的价值和重量来决定是否选择这个物品,从而更新dp数组。

4,具体的算法步骤如下

4.1. 初始化dp数组,dp[i][j] = 0,对于所有i和j。
4.2. 对于每个物品i,遍历所有可能的背包容量j(从0到V),如果物品i的重量小于等于j,那么考虑两种情况:选择物品i或者不选择物品i。
  如果选择物品i,那么dp[i][j] = max(dp[i][j], dp[i-1][j-wi] + vi);
  如果不选择物品i,那么dp[i][j] = dp[i-1][j]。
4.3. 最后,dp[n][V]就是我们要求的答案,即在不超过背包容量的情况下,选择一些物品可以获得的最大价值。

5.算法分析

这个算法的时间复杂度是O(nV),其中n是物品的数量,V是背包的容量。这是因为我们需要遍历所有的物品和背包容量来更新dp数组。
空间复杂度也是O(nV),因为我们需要存储整个dp数组。

6.列表分析结果

.编程实现

def knapsack_json_list(goods_list, capacity):
    '''
    用动态规划算法实现0/1背包问题
    该算法的时间复杂度为O(n * capacity),其中n为物品数量,capacity为背包容量。空间复杂度为O(n * capacity)。
    '''

    nums = len(goods_list)
    dp = [[0 for c in range(capacity + 1)] for _ in range(nums + 1)]
    for i in range(1, nums + 1):
        for c in range(1, capacity + 1):
            weight = goods_list[i - 1]["weight"]
            value = goods_list[i - 1]["value"]
            # 当前商品重量小于等于当前背包容量,则选择商品
            if weight <= c:
                dp[i][c] = max(dp[i - 1][c], dp[i - 1][c - weight] + value)
            else:
                dp[i][c] = dp[i - 1][c]
    # 记录决策过程
    print("最优方案,价值决策过程为:")
    c = capacity
    for i in range(nums, 0, -1):
        if dp[i][c] != dp[i - 1][c]:
            print('选择商品:%s, 价值:%s, 重量:%s' % (
                goods_list[i - 1]["name"], goods_list[i - 1]["value"], goods_list[i - 1]["weight"]))
            c -= goods_list[i - 1]["weight"]
    return dp[-1][-1]


if __name__ == "__main__":

    # 商品列表
    goods_list = [{"name": "饼干", "value": 9, "weight": 4},
                  {"name": "面包", "value": 10, "weight": 5},
                  {"name": "牛奶", "value": 9, "weight": 4},
                  {"name": "汽水", "value": 2, "weight": 3},
                  {"name": "啤酒", "value": 24, "weight": 10},
                  ]
    # 背包容量
    capacity = 13
    # 最优方案,总价值28,总体积13
    rsp_new = knapsack_json_list(goods_list, capacity)
    print("最大价值为:", rsp_new)

.运行结果

 ==================================end ==================================

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值